±à¼ÍƼö: |
CPU
ÄÚÖÃÉÙÁ¿µÄ¸ßËÙ»º´æµÄÖØÒªÐÔ²»ÑÔ¶øÓ÷£¬ÔÚÌå»ý¡¢³É±¾¡¢Ð§ÂʵÈÒòËØÏ²úÉúÁ˵±½ñÓõ½µÄ¼ÆËã»úµÄ´æ´¢½á¹¹¡£
±¾ÎÄÀ´×ÔÓÚinfoq£¬ÓÉ»ðÁú¹ûÈí¼þAnna±à¼¡¢ÍƼö¡£ |
|
CPU ƵÂÊÌ«¿ì£¬Æä´¦ÀíËÙ¶ÈÔ¶¿ìÓÚ´æ´¢½éÖʵĶÁд¡£Òò´Ë£¬µ¼Ö CPU
×ÊÔ´µÄÀË·Ñ£¬ÐèÒªÓÐЧ½â¾ö IO ËÙ¶ÈºÍ CPU ÔËËãËÙ¶ÈÖ®¼äµÄ²»Æ¥ÅäÎÊÌ⡣оƬ¼¶¸ßËÙ»º´æ¿É´ó´ó¼õÉÙÖ®¼äµÄ´¦ÀíÑÓ³Ù¡£CPU
ÖÆÔ칤ÒյĽø²½Ê¹µÃÔÚ±ÈÒÔǰ¸üСµÄ¿Õ¼äÖа²×°ÊýÊ®ÒÚ¸ö¾§Ìå¹Ü£¬Èç´Ë¿ÉΪ»º´æÁô³ö¸ü¶à¿Õ¼ä£¬Ê¹Æä¾¡¿ÉÄܵؿ¿½üºËÐÄ¡£
CPU ÄÚÖÃÉÙÁ¿µÄ¸ßËÙ»º´æµÄÖØÒªÐÔ²»ÑÔ¶øÓ÷£¬ÔÚÌå»ý¡¢³É±¾¡¢Ð§ÂʵÈÒòËØÏ²úÉúÁ˵±½ñÓõ½µÄ¼ÆËã»úµÄ´æ´¢½á¹¹¡£
½é ÉÜ
¼ÆËã»úµÄÄÚ´æ¾ßÓлùÓÚËٶȵIJã´Î½á¹¹£¬CPU ¸ßËÙ»º´æÎ»Óڸòã´Î½á¹¹µÄ¶¥²¿£¬ÊǽéÓÚ CPU Äں˺ÍÎïÀíÄÚ´æ(¶¯Ì¬ÄÚ´æ
DRAM)Ö®¼äµÄÈô¸É¿é¾²Ì¬Äڴ棬ÊÇ×î¿ìµÄ¡£ËüÒ²ÊÇ×î¿¿½üÖÐÑë´¦ÀíµÄµØ·½£¬ÊÇ CPU ±¾ÉíµÄÒ»²¿·Ö£¬Ò»°ãÖ±½Ó¸ú
CPU оƬ¼¯³É¡£
CPU ¼ÆË㣺³ÌÐò±»Éè¼ÆÎªÒ»×éÖ¸Á×îÖÕÓÉ CPU ÔËÐС£

×°ÔØ³ÌÐòºÍÊý¾Ý£¬ÏÈ´Ó×î½üµÄÒ»¼¶»º´æ¶ÁÈ¡£¬ÈçÓоÍÖ±½Ó·µ»Ø£¬Öð²ã¶ÁÈ¡£¬Ö±ÖÁ´ÓÄÚ´æ¼°ÆäËüÍⲿ´æ´¢ÖмÓÔØ£¬²¢½«¼ÓÔØµÄÊý¾ÝÒÀ´Î·ÅÈ뻺´æ¡£
¸ßËÙ»º´æÖеÄÊý¾Ýд»ØÖ÷´æ²¢·ÇÁ¢¼´Ö´ÐУ¬Ð´»ØÖ÷´æµÄʱ»ú£º
1.»º´æÂúÁË£¬²ÉÓÃÏȽøÏȳö»ò×î¾ÃδʹÓõÄ˳Ðòд»Ø£»
2.#Lock Ðźţ¬»º´æÒ»ÖÂÐÔÐÒ飬Ã÷È·ÒªÇóÊý¾Ý¼ÆËãÍê³ÉºóÒªÁ¢Âíͬ²½»ØÖ÷´æ¡£
CPU »º´æµÄ½á¹¹
ÏÖ´úµÄ CPU »º´æ½á¹¹±»·ÖΪ¶à´¦Àí¡¢¶àºË¡¢¶à¼¶µÄ²ã´Î¡£
2.1 ¶à¼¶»º´æ½á¹¹
·ÖΪÈý¸öÖ÷Òª¼¶±ð£¬¼´ L1£¬L2 ºÍ L3¡£Àë CPU Ô½½üµÄ»º´æ£¬¶ÁȡЧÂÊÔ½¸ß£¬´æ´¢ÈÝÁ¿Ô½Ð¡£¬Ôì¼ÛÔ½¸ß¡£

L1 ¸ßËÙ»º´æÊÇϵͳÖдæÔÚµÄ×î¿ìµÄÄÚ´æ¡£¾ÍÓÅÏȼ¶¶øÑÔ£¬L1 »º´æ¾ßÓÐ CPU ÔÚÍê³ÉÌØ¶¨ÈÎÎñʱ×î¿ÉÄÜÐèÒªµÄÊý¾Ý£¬´óСͨ³£¿É´ï
256KB£¬Ò»Ð©¹¦ÄÜÇ¿´óµÄ CPU Õ¼Óýü 1MB¡£Ä³Ð©·þÎñÆ÷оƬ×é(Èç Intel ¸ß¶Ë Xeon
CPU)¾ßÓÐ 1-2MB¡£L1 »º´æÍ¨³£ÓÖ·ÖΪָÁ´æºÍÊý¾Ý»º´æ¡£Ö¸Á´æ´¦ÀíÓÐ¹Ø CPU ±ØÐëÖ´ÐеIJÙ×÷µÄÐÅÏ¢£¬Êý¾Ý»º´æÔò±£ÁôÒªÔÚÆäÉÏÖ´ÐвÙ×÷µÄÊý¾Ý¡£Èç´Ë£¬¼õÉÙÁËÕùÓÃ
Cache ËùÔì³ÉµÄ³åÍ»£¬Ìá¸ßÁË´¦ÀíÆ÷ЧÄÜ¡£
L2 ¼¶»º´æ±È L1 Âý£¬µ«´óС¸ü´ó£¬Í¨³£ÔÚ 256KB µ½ 8MB Ö®¼ä£¬¹¦ÄÜÇ¿´óµÄ CPU ÍùÍù»á³¬¹ý´Ë´óС¡£L2
¸ßËÙ»º´æ±£´æÏÂÒ»²½¿ÉÄÜÓÉ CPU ·ÃÎʵÄÊý¾Ý¡£´ó¶àÊý CPU ÖУ¬L1 ºÍ L2 ¸ßËÙ»º´æÎ»ÓÚ CPU
Äں˱¾Éí£¬Ã¿¸öÄں˶¼ÓÐ×Ô¼ºµÄ¸ßËÙ»º´æ¡£
L3 ¼¶¸ßËÙ»º´æÊÇ×î´óµÄ¸ßËÙ´æ´¢µ¥Ôª£¬Ò²ÊÇ×îÂýµÄ¡£´óС´Ó 4MB µ½ 50MB ÒÔÉÏ¡£ÏÖ´ú CPU
ÔÚ CPU ÂãÆ¬ÉϾßÓÐÓÃÓÚ L3 ¸ßËÙ»º´æµÄרÓÿռ䣬ÇÒÕ¼ÓÃÁ˺ܴóÒ»²¿·Ö¿Õ¼ä¡£
2.2 ¶à´¦ÀíÆ÷»º´æ½á¹¹
¼ÆËã»úÔçÒѽøÈë¶àºËʱ´ú£¬Èí¼þÒ²ÔËÐÐÔÚ¶àºË»·¾³¡£Ò»¸ö´¦ÀíÆ÷¶ÔÓ¦Ò»¸öÎïÀí²å²Û¡¢°üº¬¶à¸öºË£¨Ò»¸öºË°üº¬¼Ä´æÆ÷¡¢L1
Cache¡¢L2 Cache£©£¬¶àºË¼ä¹²Ïí L3 Cache£¬¶à´¦ÀíÆ÷¼äͨ¹ý QPI ×ÜÏßÏàÁ¬¡£

L1 ºÍ L2 »º´æÎª CPU µ¥¸öºËÐÄ˽ÓеĻº´æ£¬L3 »º´æÊÇͬ²å²ÛµÄËùÓкËÐͼ¹²ÏíµÄ»º´æ¡£
L1 »º´æ±»·Ö³É¶ÀÁ¢µÄ 32K Êý¾Ý»º´æºÍ 32K Ö¸Á´æ£¬L2 »º´æ±»Éè¼ÆÎª L1 Óë¹²ÏíµÄ
L3 »º´æÖ®¼äµÄ»º³å¡£´óСΪ 256K£¬Ö÷Òª×÷Ϊ L1 ºÍ L3 Ö®¼äµÄ¸ßЧÄÚ´æ·ÃÎʶÓÁÐ,ͬʱ°üº¬Êý¾ÝºÍÖ¸Áî¡£L3
»º´æ°üÀ¨ÁËÔÚͬһ¸ö²ÛÉϵÄËùÓÐ L1 ºÍ L2 »º´æÖеÄÊý¾Ý¡£ÕâÖÖÉè¼ÆÏûºÄÁ˿ռ䣬µ«¿ÉÀ¹½Ø¶Ô L1 ºÍ
L2 »º´æµÄÇëÇ󣬼õÇáÁ˸÷¸öºËÐÄ˽ÓÐµÄ L1 ºÍ L2 »º´æµÄ¸ºµ£¡£
2.3 Cache Line
Cache ´æ´¢Êý¾ÝÒԹ̶¨´óСΪµ¥Î»£¬³ÆÎª Cache Line/Block¡£¸ø¶¨ÈÝÁ¿ºÍ Cache
Line size£¬Ôò¾Í¹Ì¶¨ÁË´æ´¢µÄÌõÄ¿¸öÊý¡£¶ÔÓÚ X86£¬Cache Line ´óСÓë DDR Ò»´Î·Ã´æÄܵõ½µÄÊý¾Ý´óСһÖ£¬¼´
64B¡£¾ÉµÄ ARM ¼Ü¹¹µÄ Cache Line ÊÇ 32B£¬Òò´Ë¾³£ÊÇÒ»´ÎÌîÁ½¸ö Cache Line¡£CPU
´Ó Cache »ñÈ¡Êý¾ÝµÄ×îСµ¥Î»Îª×Ö½Ú£¬Cache ´Ó Memory »ñÈ¡µÄ×îСµ¥Î»ÊÇ Cache
Line£¬Memory ´Ó´ÅÅÌ»ñÈ¡Êý¾Ýͨ³£×îСÊÇ 4K¡£
Cache ·Ö³É¶à¸ö×飬ÿ×é·Ö³É¶à¸ö Cache Line ÐУ¬´óÖÂÈçÏÂͼ£º

Linux ϵͳÏÂʹÓÃÒÔÏÂÃüÁî²é¿´ Cache ÐÅÏ¢£¬lscpu ÃüÁîÒ²¿É¡£

»º´æµÄ´æÈ¡ÓëÒ»ÖÂ
ÏÂÃæ±í¸ñÃèÊöÁ˲»Í¬´æ´¢½éÖʵĴæÈ¡ÐÅÏ¢£¬¹©²Î¿¼¡£
´æÈ¡ËÙ¶È£º¼Ä´æÆ÷ > cache(L1~L3) > RAM > Flash >
Ó²ÅÌ > ÍøÂç´æ´¢

ÒÔ 2.2Ghz ƵÂ浀 CPU ΪÀý£¬Ã¿¸öʱÖÓÖÜÆÚ´ó¸ÅÊÇ 0.5 ÄÉÃë¡£
3.1 ¶ÁÈ¡´æ´¢Æ÷Êý¾Ý
°´ CPU ²ã¼¶»º´æ½á¹¹£¬È¡Êý¾ÝµÄ˳ÐòÊÇÏÈ»º´æÔÙÖ÷´æ¡£µ±È»£¬ÈçÊý¾ÝÀ´×ԼĴæÆ÷£¬Ö»ÐèÖ±½Ó¶ÁÈ¡·µ»Ø¼´¿É¡£
1) Èç CPU Òª¶ÁµÄÊý¾ÝÔÚ L1 cache£¬Ëø×¡ cache ÐУ¬¶ÁÈ¡ºó½âËø¡¢·µ»Ø
2) Èç CPU Òª¶ÁµÄÊý¾ÝÔÚ L2 cache£¬Êý¾ÝÔÚ L2 Àï¼ÓËø£¬½«Êý¾Ý¸´ÖƵ½ L1£¬ÔÙÖ´ÐжÁ
L1
3) Èç CPU Òª¶ÁµÄÊý¾ÝÔÚ L3 cache£¬Ò²Ò»Ñù£¬Ö»²»¹ýÏÈÓÉ L3 ¸´ÖƵ½ L2£¬ÔÙ´Ó L2
¸´ÖƵ½ L1£¬×îºó´Ó L1 µ½ CPU
4) Èç CPU Ðè¶ÁÈ¡Äڴ棬ÔòÊ×ÏÈ֪ͨÄÚ´æ¿ØÖÆÆ÷Õ¼ÓÃ×ÜÏß´ø¿í£¬ºóÄÚ´æ¼ÓËø¡¢·¢Æð¶ÁÇëÇ󡢵ȴý»ØÓ¦£¬»ØÓ¦Êý¾Ý±£´æÖÁ
L3£¬L2,L1£¬ÔÙ´Ó L1 µ½ CPU ºó½â³ý×ÜÏßËø¶¨¡£
3.2 »º´æÃüÖÐÓëÑÓ³Ù
ÓÉÓÚÊý¾ÝµÄ¾Ö²¿ÐÔÔÀí£¬CPU ÍùÍùÐèÒªÔÚ¶Ìʱ¼äÄÚÖØ¸´¶à´Î¶ÁÈ¡Êý¾Ý£¬ÄÚ´æµÄÔËÐÐÆµÂÊÔ¶¸ú²»ÉÏ CPU
µÄ´¦ÀíËÙ¶È£¬»º´æµÄÖØÒªÐÔ±»Í¹ÏÔ¡£CPU ¿É±Ü¿ªÄÚ´æÔÚ»º´æÀï¶ÁÈ¡µ½ÏëÒªµÄÊý¾Ý£¬³ÆÖ®ÎªÃüÖС£L1 µÄÔËÐÐËٶȺܿ죬µ«ÈÝÁ¿ºÜС£¬ÔÚ
L1 ÀïÃüÖеĸÅÂÊ´ó¸ÅÔÚ 80%×óÓÒ£¬L2¡¢L3 µÄ»úÖÆÒ²ÀàËÆ¡£ÕâÑùÒ»À´£¬CPU ÐèÒªÔÚÖ÷´æÖжÁÈ¡µÄÊý¾Ý´ó¸ÅΪ
5%-10%£¬ÆäÓàÃüÖÐÈ«²¿¿ÉÒÔÔÚ L1¡¢L2¡¢L3 ÖлñÈ¡£¬´ó´ó¼õÉÙÁËϵͳµÄÏìӦʱ¼ä¡£
¸ßËÙ»º´æÖ¼ÔÚ¼Ó¿ìÖ÷ÄÚ´æºÍ CPU Ö®¼äµÄÊý¾Ý´«Êä¡£´ÓÄÚ´æ·ÃÎÊÊý¾ÝËùÐèµÄʱ¼ä³ÆÎªÑÓ³Ù£¬L1 ¾ßÓÐ×îµÍÑÓ³ÙÇÒ×î½Ó½üºËÐÄ£¬¶ø
L3 ¾ßÓÐ×î¸ßµÄÑÓ³Ù¡£»º´æÎ´ÃüÖÐʱ£¬ÓÉÓÚ CPU Ðè´ÓÖ÷´æ´¢Æ÷ÖлñÈ¡Êý¾Ý£¬µ¼ÖÂÑÓ³Ù»á¸ü¶à¡£
3.3 »º´æÌæ»»²ßÂÔ
Cache ÀïµÄÊý¾ÝÊÇ Memory Öг£ÓÃÊý¾ÝµÄÒ»¸ö¿½±´£¬´æÂúºóÔÙ´æÈëÒ»¸öеÄÌõĿʱ£¬¾ÍÐèÒª°ÑÒ»¸ö¾ÉµÄÌõÄ¿´Ó»º´æÖÐÄõô£¬Õâ¸ö¹ý³Ì³ÆÎª
evict¡£»º´æ¹ÜÀíµ¥ÔªÍ¨¹ýÒ»¶¨µÄËã·¨¾ö¶¨ÄÄЩÊý¾ÝÐèÒª´Ó Cache ÀïÒÆ³öÈ¥£¬³ÆÎªÌæ»»²ßÂÔ¡£×î¼òµ¥µÄ²ßÂÔΪ
LRU£¬ÔÚ CPU Éè¼ÆµÄ¹ý³ÌÖУ¬Í¨³£»á¶ÔÌæ»»²ßÂÔ½øÐиĽø£¬Ã¿Ò»¿îоƬ¼¸ºõ¶¼Ê¹ÓÃÁ˲»Í¬µÄÌæ»»²ßÂÔ¡£
3.4 MESI »º´æÒ»ÖÂÐÔ
ÔÚ¶à CPU µÄϵͳÖУ¬Ã¿¸ö CPU ¶¼ÓÐ×Ô¼ºµÄ±¾µØ Cache¡£Òò´Ë£¬Í¬Ò»¸öµØÖ·µÄÊý¾Ý£¬ÓпÉÄÜÔÚ¶à¸ö
CPU µÄ±¾µØ Cache Àï´æÔÚ¶à·Ý¿½±´¡£ÎªÁ˱£Ö¤³ÌÐòÖ´ÐеÄÕýÈ·ÐÔ£¬¾Í±ØÐ뱣֤ͬһ¸ö±äÁ¿£¬Ã¿¸ö CPU
¿´µ½µÄÖµ¶¼ÊÇÒ»ÑùµÄ¡£Ò²¾ÍÊÇ˵£¬±ØÐëÒª±£Ö¤Ã¿¸ö CPU µÄ±¾µØ Cache ÖÐÄܹ»Èçʵ·´Ó³ÄÚ´æÖеÄÕæÊµÊý¾Ý¡£
¼ÙÉèÒ»¸ö±äÁ¿ÔÚ CPU0 ºÍ CPU1 µÄ±¾µØ Cache Öж¼ÓÐÒ»·Ý¿½±´£¬µ± CPU0 ÐÞ¸ÄÁËÕâ¸ö±äÁ¿Ê±£¬¾Í±ØÐëÒÔijÖÖ·½Ê½Í¨Öª
CPU1£¬ÒÔ±ã CPU1 Äܹ»¼°Ê±¸üÐÂ×Ô¼º±¾µØ Cache ÖеĿ½±´£¬ÕâÑù²ÅÄÜÔÚÁ½¸ö CPU Ö®¼ä±£³ÖÊý¾ÝµÄͬ²½£¬CPU
Ö®¼äµÄÕâÖÖͬ²½Óнϴó¿ªÏú¡£
Ϊ±£Ö¤»º´æÒ»Ö£¬ÏÖ´ú CPU ʵÏÖÁ˷dz£¸´ÔӵĶàºË¡¢¶à¼¶»º´æÒ»ÖÂÐÔÐÒé MESI, MESI ¾ßÌåµÄ²Ù×÷ÉÏ»áÕë¶Ôµ¥¸ö»º´æÐнøÐмÓËø¡£
MESI£ºModified Exclusive Shared or Invalid
1) ÐÒéÖеÄ״̬
CPU ÖÐÿ¸ö»º´æÐÐʹÓà 4 ÖÖ״̬½øÐбê¼Ç(ʹÓöîÍâµÄÁ½Î» bit ±íʾ)
M: Modified
¸Ã»º´æÐÐÖ»±»»º´æÔڸà CPU µÄ»º´æÖУ¬ÇÒ±»Ð޸Ĺý(dirty),¼´ÓëÖ÷´æÖеÄÊý¾Ý²»Ò»Ö£¬¸Ã»º´æÐÐÖеÄÄÚÈÝÐèÔÚδÀ´µÄij¸öʱ¼äµã(ÔÊÐíÆäËü
CPU ¶ÁÈ¡Ö÷´æÖÐÏàÓ¦ÄÚ´æÖ®Ç°)д»ØÖ÷´æ¡£µ±±»Ð´»ØÖ÷´æÖ®ºó£¬¸Ã»º´æÐеÄ״̬±ä³É¶ÀÏí(exclusive)״̬
E: Exclusive
¸Ã»º´æÐÐÖ»±»»º´æÔڸà CPU µÄ»º´æÖУ¬Î´±»Ð޸ģ¬ÓëÖ÷´æÖÐÊý¾ÝÒ»Ö¡£ÔÚÈκÎʱ¿Ìµ±ÓÐÆäËü CPU ¶ÁÈ¡¸ÃÄÚ´æÊ±±ä³É
shared ״̬¡£Í¬Ñù£¬µ±Ð޸ĸûº´æÐÐÖÐÄÚÈÝʱ£¬¸Ã״̬¿ÉÒÔ±ä³É Modified ״̬.
S: Shared
Òâζ¸Ã»º´æÐпÉÄܱ»¶à¸ö CPU »º´æ£¬¸÷¸ö»º´æÖеÄÊý¾ÝÓëÖ÷´æÊý¾ÝÒ»Ö£¬µ±ÓÐÒ»¸ö CPU Ð޸ĸûº´æÐÐÖУ¬ÆäËü
CPU Öиûº´æÐпÉÒÔ±»×÷·Ï(Invalid).
I: Invalid£¬»º´æÎÞЧ(¿ÉÄÜÆäËü CPU ÐÞ¸ÄÁ˸ûº´æÐÐ)
2) ״̬Çл»¹ØÏµ
ÓÉÏÂͼ¿É¿´³ö cache ÊÇÈçºÎ±£Ö¤ËüµÄÊý¾ÝÒ»ÖÂÐԵġ£

Æ©È磬µ±Ç°ºËÐÄÒª¶ÁÈ¡µÄÊý¾Ý¿éÔÚÆäºËÐÄµÄ cache ״̬Ϊ Invalid£¬ÔÚÆäËûºËÐÄÉÏ´æÔÚÇÒ״̬Ϊ
Modified µÄÇé¿ö¡£¿ÉÒÔ´Óµ±Ç°ºËÐÄºÍÆäËüºËÐÄÁ½¸ö½Ç¶È¹Û²ì£¬ÆäËüºËÐĽǶȣºµ±Ç°×´Ì¬Îª Modified£¬ÆäËüºËÐÄÏë¶ÁÕâ¸öÊý¾Ý¿é(ͼÖÐ
Modified µ½ Shared µÄÂÌÉ«ÐéÏß)£ºÏȰѸıäºóµÄÊý¾ÝдÈëµ½ÄÚ´æÖÐ(ÏÈÓÚÆäËüºËÐĵĶÁ)£¬²¢¸üиÃ
cache ״̬Ϊ Share.µ±Ç°ºËÐĽǶȣºµ±Ç°×´Ì¬Îª Invalid£¬Ïë¶ÁÕâ¸öÊý¾Ý¿é(ͼÖÐ Invalid
µ½ Shared µÄÂÌɫʵÏß)£ºÕâÖÖÇé¿öÏ»á´ÓÄÚ´æÖÐÖØÐ¼ÓÔØ£¬²¢¸üиà cache ״̬ Share
ÒÔϱí¸ñ´ÓÕâÁ½¸ö½Ç¶ÈÁоÙÁËËùÓÐÇé¿ö£¬¹©²Î¿¼£º

3) »º´æµÄ²Ù×÷ÃèÊö
Ò»¸öµäÐÍϵͳÖлáÓм¸¸ö»º´æ(ÿ¸öºËÐͼÓÐ)¹²ÏíÖ÷´æ×ÜÏߣ¬Ã¿¸öÏàÓ¦µÄ CPU »á·¢³ö¶ÁдÇëÇ󣬶ø»º´æµÄÄ¿µÄÊÇΪÁ˼õÉÙ
CPU ¶Áд¹²ÏíÖ÷´æµÄ´ÎÊý¡£
Ò»¸ö»º´æ³ýÔÚ Invalid ״̬Íâ¶¼¿ÉÒÔÂú×ã CPU µÄ¶ÁÇëÇó£¬Ò»¸ö Invalid µÄ»º´æÐбØÐë´ÓÖ÷´æÖжÁÈ¡(±ä³É
S »ò E ״̬)À´Âú×ã¸Ã CPU µÄ¶ÁÇëÇó¡£
Ò»¸öдÇëÇóÖ»ÓÐÔڸûº´æÐÐÊÇ M »ò E ״̬ʱ²ÅÄܱ»Ö´ÐУ¬Èç¹û»º´æÐд¦ÓÚ S ״̬£¬±ØÐëÏȽ«ÆäËü»º´æÖиûº´æÐбä³É
Invalid(²»ÔÊÐí²»Í¬ CPU ͬʱÐÞ¸Äͬһ»º´æÐУ¬¼´Ê¹Ð޸ĸûº´æÐÐÖв»Í¬Î»ÖõÄÊý¾ÝÒ²²»¿É)£¬¸Ã²Ù×÷³£ÒԹ㲥·½Ê½À´Íê³É¡£
»º´æ¿ÉÒÔËæÊ±½«Ò»¸ö·Ç M ״̬µÄ»º´æÐÐ×÷·Ï£¬»ò±ä³É Invalid£¬¶øÒ»¸ö M ״̬µÄ»º´æÐбØÐëÏȱ»Ð´»ØÖ÷´æ¡£Ò»¸ö´¦ÓÚ
M ״̬µÄ»º´æÐбØÐëʱ¿Ì¼àÌýËùÓÐÊÔͼ¶Á¸Ã»º´æÐÐÏà¶ÔÖ÷´æµÄ²Ù×÷£¬²Ù×÷±ØÐëÔÚ»º´æ½«¸Ã»º´æÐÐд»ØÖ÷´æ²¢½«×´Ì¬±ä³É
S ״̬֮ǰ±»ÑÓ³ÙÖ´ÐС£
Ò»¸ö´¦ÓÚ S ״̬µÄ»º´æÐÐÐè¼àÌýÆäËü»º´æÊ¹¸Ã»º´æÐÐÎÞЧ»ò¶ÀÏí¸Ã»º´æÐеÄÇëÇ󣬲¢½«¸Ã»º´æÐбä³ÉÎÞЧ¡£
Ò»¸ö´¦ÓÚ E ״̬µÄ»º´æÐÐÒ²±ØÐë¼àÌýÆäËü¶ÁÖ÷´æÖиûº´æÐеIJÙ×÷£¬Ò»µ©ÓÐÕâÖÖ²Ù×÷£¬¸Ã»º´æÐÐÐè±ä³É
S ״̬¡£
¶ÔÓÚ M ºÍ E ״̬¶øÑÔ×ÜÊǾ«È·µÄ£¬ºÍ¸Ã»º´æÐеÄÕæÕý״̬ÊÇÒ»Öµġ£¶ø S ״̬¿ÉÄÜÊÇ·ÇÒ»Öµģ¬Èç¹ûÒ»¸ö»º´æ½«´¦ÓÚ
S ״̬µÄ»º´æÐÐ×÷·ÏÁË£¬¶øÁíÒ»¸ö»º´æÊµ¼ÊÉÏ¿ÉÄÜÒѾ¶ÀÏíÁ˸ûº´æÐУ¬µ«ÊǸûº´æÈ´²»»á½«¸Ã»º´æÐÐÉýǨΪ
E ״̬£¬ÊÇÒòΪÆäËü»º´æ²»»á¹ã²¥×÷·Ïµô¸Ã»º´æÐеÄ֪ͨ£¬Í¬Ñù£¬ÓÉÓÚ»º´æ²¢Ã»Óб£´æ¸Ã»º´æÐÐµÄ copy
µÄÊýÁ¿£¬Òò´ËҲûÓа취ȷ¶¨×Ô¼ºÊÇ·ñÒѾ¶ÀÏíÁ˸ûº´æÐС£
´ÓÉÏÃæµÄÒâÒåÀ´¿´£¬E ״̬ÊÇÒ»ÖÖͶ»úÐÔµÄÓÅ»¯£ºÈç¹ûÒ»¸ö CPU ÏëÐÞ¸ÄÒ»¸ö´¦ÓÚ S ״̬µÄ»º´æÐУ¬×ÜÏßÊÂÎñÐèÒª½«ËùÓиûº´æÐеÄ
copy ±ä³É Invalid ״̬£¬¶øÐÞ¸Ä E ״̬µÄ»º´æ²»ÐèҪʹÓÃ×ÜÏßÊÂÎñ¡£
´úÂëÉè¼ÆµÄ¿¼Á¿
Àí½â¼ÆËã»ú´æ´¢Æ÷²ã´Î½á¹¹¶ÔÓ¦ÓóÌÐòµÄÐÔÄÜÓ°Ïì¡£Èç¹ûÐèÒªµÄ³ÌÐòÔÚ CPU ¼Ä´æÆ÷ÖУ¬Ö¸ÁîÖ´ÐÐʱ 1
¸öÖÜÆÚÄÚ¾ÍÄÜ·ÃÎʵ½£»Èç¹ûÔÚ CPU Cache ÖУ¬Ðè 1~30 ¸öÖÜÆÚ£»Èç¹ûÔÚÖ÷´æÖУ¬ÐèÒª 50~200
¸öÖÜÆÚ£»ÔÚ´ÅÅÌÉÏ£¬´ó¸ÅÐèÒªÍò¼¶ÖÜÆÚ¡£ÁíÍ⣬Cache Line µÄ´æÈ¡Ò²ÊÇ´úÂëÉè¼ÆÕßÐèÒª¹Ø×¢µÄ²¿·Ö,
ÒÔ¹æ±Üα¹²ÏíµÄÖ´Ðг¡¾°¡£Òò´Ë£¬³ä·ÖÀûÓûº´æµÄ½á¹¹ºÍ»úÖÆ¿ÉÓÐЧÌá¸ß³ÌÐòµÄÖ´ÐÐÐÔÄÜ¡£
4.1 ¾Ö²¿ÐÔÌØÐÔ
Ò»µ© CPU Òª´ÓÄÚ´æ»ò´ÅÅÌÖзÃÎÊÊý¾Ý¾Í»á²úÉúÒ»¸öºÜ´óµÄʱÑÓ£¬³ÌÐòÐÔÄÜÏÔÖø½µµÍ£¬Îª´ËÎÒÃDz»µÃ²»Ìá¸ß
Cache ÃüÖÐÂÊ£¬Ò²¾ÍÊdzä·Ö·¢»Ó¾Ö²¿ÐÔÔÀí¡£Ò»°ãÀ´Ëµ£¬¾ßÓÐÁ¼ºÃ¾Ö²¿ÐԵijÌÐò»á±È¾Ö²¿ÐԽϲîµÄ³ÌÐòÔËÐеøü¿ì£¬³ÌÐòÐÔÄܸüºÃ¡£
¾Ö²¿ÐÔ»úÖÆÈ·±£ÔÚ·ÃÎÊ´æ´¢É豸ʱ£¬´æÈ¡Êý¾Ý»òÖ¸Áî¶¼Ç÷ÓÚ¾Û¼¯ÔÚһƬÁ¬ÐøµÄÇøÓò¡£Ò»¸öÉè¼ÆÓÅÁ¼µÄ¼ÆËã»ú³ÌÐòͨ³£¾ßÓкܺõľֲ¿ÐÔ£¬Ê±¼ä¾Ö²¿ÐԺͿռä¾Ö²¿ÐÔ¡£
1) ʱ¼ä¾Ö²¿ÐÔ
Èç¹ûÒ»¸öÊý¾Ý/ÐÅÏ¢Ïî±»·ÃÎʹýÒ»´Î£¬ÄÇôºÜÓпÉÄÜËü»áÔں̵ܶÄʱ¼äÄÚÔٴα»·ÃÎÊ¡£±ÈÈçÑ»·¡¢µÝ¹é¡¢·½·¨µÄ·´¸´µ÷Óõȡ£
2) ¿Õ¼ä¾Ö²¿ÐÔ
Ò»¸ö Cache Line ÓÐ 64 ×ֽڿ飬¿ÉÒÔ³ä·ÖÀûÓÃÒ»´Î¼ÓÔØ 64 ×ֽڵĿռ䣬°Ñ³ÌÐòºóÐø»á·ÃÎʵÄÊý¾Ý£¬Ò»´ÎÐÔÈ«²¿¼ÓÔØ½øÀ´£¬´Ó¶øÌá¸ß
Cache Line ÃüÖÐÂÊ£¨¶ø·ÇÖØÐÂȥѰַ¶ÁÈ¡£©¡£Èç¹ûÒ»¸öÊý¾Ý±»·ÃÎÊ£¬ÄÇôºÜÓпÉÄÜλÓÚÕâ¸öÊý¾Ý¸½½üµÄÆäËüÊý¾ÝÒ²»áºÜ¿ì±»·ÃÎʵ½¡£±ÈÈç˳ÐòÖ´ÐеĴúÂë¡¢Á¬Ðø´´½¨µÄ¶à¸ö¶ÔÏó¡¢Êý×éµÈ¡£Êý×é¾ÍÊÇÒ»ÖְѾֲ¿ÐÔÔÀíÀûÓõ½¼«ÖµÄÊý¾Ý½á¹¹¡£
3) ´úÂëʾÀý
ʾÀý 1£¬(C ÓïÑÔ)
//³ÌÐò array1.c
¶àάÊý×é½»»»ÐÐÁзÃÎÊ˳Ðò
char array[10240][10240];
int main(int argc, char *argv[]){
int i = 0;
int j = 0;
for(i=0; i < 10240 ; i++) {
for(j=0; j < 10240 ; j++) {
array[i][j] = ¡®A¡¯; //°´ÐнøÐзÃÎÊ
}
}
return 0;
} |
ºìÉ«×ÖÌåµÄ´úÂëµ÷ÕûΪ£º arrayj = ¡®A¡¯; //°´ÁнøÐзÃÎÊ
±àÒë¡¢ÔËÐнá¹ûÈçÏ£º

´Ó²âÊÔ½á¹û¿´£¬µÚÒ»¸ö³ÌÐòÔËÐкÄʱ 0.265 Ã룬µÚ¶þ¸ö 1.998
Ã룬ÊǵÚÒ»¸ö³ÌÐòµÄ 7.5 ±¶¡£
½á¹û·ÖÎö
Êý×éÔªËØ´æ´¢ÔÚµØÖ·Á¬ÐøµÄÄÚ´æÖУ¬¶àάÊý×éÔÚÄÚ´æÖÐÊǰ´ÐнøÐд洢¡£µÚÒ»¸ö³ÌÐò°´ÐзÃÎÊij¸öÔªËØÊ±£¬¸ÃÔªËØ¸½½üµÄÒ»¸ö
Cache Line ´óСµÄÔªËØ¶¼»á±»¼ÓÔØµ½ Cache ÖУ¬ÕâÑùÒ»À´£¬ÔÚ·ÃÎʽô°¤×ŵÄÏÂÒ»¸öÔªËØÊ±£¬¾Í¿ÉÖ±½Ó·ÃÎÊ
Cache ÖеÄÊý¾Ý£¬²»ÐèÔÙ´ÓÄÚ´æÖмÓÔØ¡£Ò²¾ÍÊÇ˵£¬¶ÔÊý×é°´ÐнøÐзÃÎÊʱ£¬¾ßÓиüºÃµÄ¿Õ¼ä¾Ö²¿ÐÔ£¬Cache
ÃüÖÐÂʸü¸ß¡£
µÚ¶þ¸ö³ÌÐò°´ÁзÃÎÊij¸öÔªËØ£¬ËäÈ»¸ÃÔªËØ¸½½üµÄÒ»¸ö Cache Line ´óСµÄÔªËØÒ²»á±»¼ÓÔØ½ø Cache
ÖУ¬µ«½ÓÏÂÀ´Òª·ÃÎʵÄÊý¾ÝÈ´²»Êǽô°¤×ŵÄÄǸöÔªËØ£¬Òò´ËºÜÓпÉÄÜ»áÔٴβúÉú Cache miss£¬¶ø²»µÃ²»´ÓÄÚ´æÖмÓÔØÊý¾Ý¡£¶øÇÒ£¬ËäÈ»
Cache ÖлᾡÁ¿±£´æ×î½ü·ÃÎʹýµÄÊý¾Ý£¬µ« Cache ´óСÓÐÏÞ£¬µ± Cache ±»Õ¼Âúʱ£¬¾Í²»µÃ²»°ÑһЩÊý¾Ý¸øÌæ»»µô¡£ÕâÒ²Êǿռä¾Ö²¿ÐÔ²îµÄ³ÌÐò¸üÈÝÒײúÉú
Cache miss µÄÖØÒªÔÒòÖ®Ò»¡£
ʾÀý 2£¬£¨Java£©
ÒÔÏ´úÂëÖ㤶ÈΪ 16 µÄ row ºÍ column Êý×飬ÔÚ Cache
Line 64 ×Ö½ÚÊý¾Ý¿éÉÏÄÚ´æµØÖ·ÊÇÁ¬ÐøµÄ£¬Äܱ»Ò»´Î¼ÓÔØµ½ Cache Line ÖУ¬ÔÚ·ÃÎÊÊý×éʱÃüÖÐÂʸߣ¬ÐÔÄÜ·¢»Óµ½¼«Ö¡£
public int run(int[]
row, int[] column) {
int sum = 0;
for(int i = 0; i < 16;i++ ) {
sum += row[i] * column[i];
}
return sum;
} |
±äÁ¿ i ÌåÏÖÁËʱ¼ä¾Ö²¿ÐÔ£¬×÷Ϊ¼ÆÊýÆ÷±»Æµ·±²Ù×÷£¬Ò»Ö±´æ·ÅÔڼĴæÆ÷ÖУ¬Ã¿´Î´Ó¼Ä´æÆ÷·ÃÎÊ£¬¶ø²»ÊÇ´Ó»º´æ»òÖ÷´æ·ÃÎÊ¡£
4.2 »º´æÐеÄËø¾ºÕù
ÔÚ¶à´¦ÀíÆ÷Ï£¬Îª±£Ö¤¸÷¸ö´¦ÀíÆ÷µÄ»º´æÒ»Ö£¬»áʵÏÖ»º´æÒ»ÖÂÐÔÐÒ飬ÿ¸ö´¦ÀíÆ÷ͨ¹ýÐá̽ÔÚ×ÜÏßÉÏ´«²¥µÄÊý¾ÝÀ´¼ì²é×Ô¼º»º´æµÄÖµÊDz»ÊǹýÆÚ£¬µ±´¦ÀíÆ÷·¢ÏÖ×Ô¼º»º´æÐжÔÓ¦µÄÄÚ´æµØÖ·±»Ð޸ģ¬¾Í»á½«µ±Ç°´¦ÀíÆ÷µÄ»º´æÐÐÖóÉÎÞЧ״̬£¬µ±´¦ÀíÆ÷Òª¶ÔÕâ¸öÊý¾Ý½øÐÐÐ޸IJÙ×÷µÄʱºò£¬»áÇ¿ÖÆÖØÐ´ÓϵͳÄÚ´æÀï°ÑÊý¾Ý¶Áµ½´¦ÀíÆ÷»º´æÀï¡£
µ±¶à¸öÏ̶߳Ôͬһ¸ö»º´æÐзÃÎÊʱ£¬ÈçÆäÖÐÒ»¸öÏß³ÌËø×¡»º´æÐУ¬È»ºó²Ù×÷£¬ÕâʱÆäËüÏß³ÌÔòÎÞ·¨²Ù×÷¸Ã»º´æÐС£ÕâÖÖÇé¿öÏ£¬ÎÒÃÇÔÚ½øÐгÌÐò´úÂëÉè¼ÆÊ±ÊÇÒª¾¡Á¿±ÜÃâµÄ¡£
4.3 α¹²ÏíµÄ¹æ±Ü
Á¬Ðø½ô´ÕµÄÄÚ´æ·ÖÅä´øÀ´¸ßÐÔÄÜ£¬µ«²¢²»´ú±íËüÒ»Ö±¶¼ÐÐÖ®ÓÐЧ£¬Î±¹²Ïí¾ÍÊÇÎÞÉùµÄÐÔÄÜɱÊÖ¡£Ëùνα¹²Ïí(False
Sharing£©£¬ÊÇÓÉÓÚÔËÐÐÔÚ²»Í¬ CPU ÉϵIJ»Í¬Ị̈߳¬Í¬Ê±Ð޸Ĵ¦ÔÚͬһ¸ö Cache Line
ÉϵÄÊý¾ÝÒýÆð¡£»º´æÐÐÉϵÄд¾ºÕùÊÇÔËÐÐÔÚ SMP ϵͳÖв¢ÐÐÏß³ÌʵÏÖ¿ÉÉìËõÐÔ×îÖØÒªµÄÏÞÖÆÒòËØ£¬Ò»°ãÀ´Ëµ£¬´Ó´úÂëÖкÜÄÑ¿´ÇåÊÇ·ñ»á³öÏÖα¹²Ïí¡£
ÔÚÿ¸ö CPU À´¿´£¬¸÷×ÔÐ޸ĵÄÊDz»Í¬µÄ±äÁ¿£¬µ«ÓÉÓÚÕâЩ±äÁ¿ÔÚÄÚ´æÖб˴˽ô°¤×Å£¬Òò´ËËüÃÇ´¦ÓÚͬһ¸ö
Cache Line ÉÏ¡£µ±Ò»¸ö CPU ÐÞ¸ÄÕâ¸ö Cache Line Ö®ºó£¬ÎªÁ˱£Ö¤Êý¾ÝµÄÒ»ÖÂÐÔ£¬±ØÈ»µ¼ÖÂÁíÒ»¸ö
CPU µÄ±¾µØ Cache µÄÎÞЧ£¬Òò¶ø´¥·¢ Cache miss£¬È»ºó´ÓÄÚ´æÖÐÖØÐ¼ÓÔØ±äÁ¿±»Ð޸ĺóµÄÖµ¡£¶à¸öÏß³ÌÆµ·±µÄÐ޸Ĵ¦ÓÚͬһ¸ö
Cache Line µÄÊý¾Ý£¬»áµ¼Ö´óÁ¿µÄ Cache miss£¬Òò¶øÔì³É³ÌÐòÐÔÄܵĴó·ùϽµ¡£
ÏÂͼ˵Ã÷ÁËÁ½¸ö²»Í¬ Core µÄÏ̸߳üÐÂͬһ»º´æÐеIJ»Í¬ÐÅÏ¢Ï

ÉÏͼ˵Ã÷ÁËα¹²ÏíµÄÎÊÌâ¡£ÔÚ Core1 ÉÏÔËÐеÄÏß³Ì×¼±¸¸üбäÁ¿ X£¬Í¬Ê± Core2 ÉϵÄÏß³Ì×¼±¸¸üбäÁ¿
Y¡£È»¶ø£¬ÕâÁ½¸ö±äÁ¿ÔÚͬһ¸ö»º´æÐÐÖС£Ã¿¸öÏ̶߳¼ÒªÈ¥¾ºÕù»º´æÐеÄËùÓÐȨÀ´¸üбäÁ¿¡£Èç¹û Core1
»ñµÃÁËËùÓÐȨ£¬»º´æ×Óϵͳ½«»áʹ Core2 ÖжÔÓ¦µÄ»º´æÐÐʧЧ¡£µ± Core2 »ñµÃÁËËùÓÐȨȻºóÖ´ÐиüвÙ×÷£¬Core1
¾ÍҪʹ×Ô¼º¶ÔÓ¦µÄ»º´æÐÐʧЧ¡£À´À´»Ø»ØµÄ¾¹ý L3 »º´æ£¬´ó´óÓ°ÏìÁËÐÔÄÜ¡£Èç¹û»¥ÏྺÕùµÄ Core λÓÚ²»Í¬µÄ²å²Û£¬¾ÍÒª¶îÍâºá¿ç²å²ÛÁ¬½Ó£¬ÎÊÌâ¿ÉÄܸü¼ÓÑÏÖØ¡£
1) ¹æ±Ü´¦Àí·½Ê½
l Ôö´óÊý×éÔªËØµÄ¼ä¸ôʹµÃ²»Í¬Ï̴߳æÈ¡µÄÔªËØÎ»ÓÚ²»Í¬ cache line£¬¿Õ¼ä»»Ê±¼ä
l ÔÚÿ¸öÏß³ÌÖд´½¨È«¾ÖÊý×é¸÷¸öÔªËØµÄ±¾µØ¿½±´£¬È»ºó½áÊøºóÔÙд»ØÈ«¾ÖÊý×é
2) ´úÂëʾÀý˵Ã÷
ʾÀý 3£¬(JAVA)
´Ó´úÂëÉè¼Æ½Ç¶È£¬Òª¿¼ÂÇÇå³þÀà½á¹¹ÖÐÄÄЩ±äÁ¿ÊDz»±ä£¬ÄÄЩÊǾ³£±ä»¯£¬ÄÄЩ±ä»¯ÊÇÍêÈ«Ï໥¶ÀÁ¢£¬ÄÄЩÊôÐÔÒ»Æð±ä»¯¡£¼ÙÈçÒµÎñ³¡¾°ÖУ¬ÏÂÃæµÄ¶ÔÏóÂú×㼸¸öÌØµã
public class
Data{
long modifyTime;
boolean flag;
long createTime;
char key;
int value;
} |
µ± value ±äÁ¿¸Ä±äʱ£¬modifyTime ¿Ï¶¨»á¸Ä±ä
createTime ±äÁ¿ºÍ key ±äÁ¿ÔÚ´´½¨ºó¾Í²»»áÔٱ仯
flag Ò²¾³£»á±ä»¯£¬²»¹ýÓë modifyTime ºÍ value
±äÁ¿ºÁÎÞ¹ØÁª
µ±ÉÏÃæµÄ¶ÔÏóÐèÒªÓɶà¸öÏß³Ìͬʱ·ÃÎÊʱ£¬´Ó Cache ½Ç¶È£¬µ±ÎÒÃÇûÓмÓÈκδëʩʱ£¬Data
¶ÔÏóËùÓеıäÁ¿¼«ÓпÉÄܱ»¼ÓÔØÔÚ L1 »º´æµÄÒ»ÐÐ Cache Line ÖС£Ôڸ߲¢·¢·ÃÎÊÏ£¬»á³öÏÖÕâÖÖÎÊÌ⣺

ÈçÉÏͼËùʾ£¬Ã¿´Î value ±ä¸üʱ£¬¸ù¾Ý MESI ÐÒ飬¶ÔÏóÆäËû CPU ÉÏÏà¹ØµÄ Cache
Line È«²¿±»ÉèÖÃΪʧЧ¡£ÆäËûµÄ´¦ÀíÆ÷ÏëÒª·ÃÎÊδ±ä»¯µÄÊý¾Ý(key ºÍ createTime)ʱ£¬±ØÐë´ÓÄÚ´æÖÐÖØÐÂÀÈ¡Êý¾Ý£¬Ôö´óÁËÊý¾Ý·ÃÎʵĿªÏú¡£
ÓÐЧµÄ Padding ·½Ê½
ÕýÈ··½Ê½Êǽ«¸Ã¶ÔÏóÊôÐÔ·Ö×飬½«Ò»Æð±ä»¯µÄ·ÅÔÚÒ»×飬ÓëÆäËûÎ޹صķÅÒ»×飬½«²»±äµÄ·Åµ½Ò»×é¡£ÕâÑùµ±Ã¿´Î¶ÔÏó±ä»¯Ê±£¬²»»á´ø¶¯ËùÓеÄÊôÐÔÖØÐ¼ÓÔØ»º´æ£¬ÌáÉýÁ˶ÁȡЧÂÊ¡£ÔÚ
JDK1.8 ǰ£¬Ò»°ãÔÚÊôÐÔ¼äÔö¼Ó³¤ÕûÐͱäÁ¿À´·Ö¸ôÿһ×éÊôÐÔ¡£±»²Ù×÷µÄÿһ×éÊôÐÔÕ¼µÄ×Ö½ÚÊý¼ÓÉÏǰºóÌî³äÊôÐÔËùÕ¼µÄ×Ö½ÚÊý£¬²»Ð¡ÓÚÒ»¸ö
cache line µÄ×Ö½ÚÊý¾Í¿É´ïµ½ÒªÇó¡£
public class
DataPadding{
long a1,a2,a3,a4,a5,a6,a7,a8;//·ÀÖ¹Óëǰһ¸ö¶ÔÏó²úÉúα¹²Ïí
int value;
long modifyTime;
long b1,b2,b3,b4,b5,b6,b7,b8;//·ÀÖ¹²»Ïà¹Ø±äÁ¿Î±¹²Ïí;
boolean flag;
long c1,c2,c3,c4,c5,c6,c7,c8;//
long createTime;
char key;
long d1,d2,d3,d4,d5,d6,d7,d8;//·ÀÖ¹ÓëÏÂÒ»¸ö¶ÔÏó²úÉúα¹²Ïí
} |
²ÉÈ¡ÉÏÊö´ëÊ©ºóµÄͼʾ£º

ÔÚ Java ÖÐ
Java8 ʵÏÖ×Ö½ÚÌî³ä±ÜÃâα¹²Ïí£¬ JVM ²ÎÊý -XX:-RestrictContended
@Contended λÓÚ sun.misc ÓÃÓÚ×¢½â java ÊôÐÔ×ֶΣ¬×Ô¶¯Ìî³ä×Ö½Ú£¬·Àֹα¹²Ïí¡£
ʾÀý 4£¬(C ÓïÑÔ)
**//****³ÌÐò thread1.c**
**¶àÏ̷߳ÃÎÊÊý¾Ý½á¹¹µÄ²»Í¬×Ö¶Î**
#include <stdio.h>
#include <pthread.h>
struct {
int a;
// charpadding[64]; // thread2.c´úÂë
int b;
}data;
void *thread_1(void) {
int i = 0;
for(i=0; i < 1000000000; i++){
data.a = 0;
}
}
void *thread_2(void) {
int i = 0;
for(i=0; i < 1000000000; i++){
data.b = 0;
}
}
|
//³ÌÐò thread2.c
Thread1.c ÖеĺìÉ«×ÖÌåÐУ¬´ò¿ª×¢Êͼ´Îª thread2.c
main()º¯ÊýºÜ¼òµ¥£¬´´½¨Á½¸öÏ̲߳¢ÔËÐÐ,²Î¿¼´úÂëÈçÏ£º
pthread_t id1;
int ret = pthread_create (&id1,NULL, (void*)thread_1,NULL); |
±àÒë¡¢ÔËÐнá¹ûÈçÏ£º

´Ó²âÊÔ½á¹û¿´£¬µÚÒ»¸ö³ÌÐòÏûºÄµÄʱ¼äÊǵڶþ¸ö³ÌÐòµÄ 3 ±¶
½á¹û·ÖÎö
´ËʾÀýÉæ¼°µ½ Cache Line µÄα¹²ÏíÎÊÌâ¡£Á½¸ö³ÌÐòΨһµÄÇø±ðÊÇ£¬µÚ¶þ¸ö³ÌÐòÖÐ×Ö¶Î a ºÍ
b ÖмäÓÐÒ»¸ö´óСΪ 64 ¸ö×Ö½ÚµÄ×Ö·ûÊý×é¡£µÚÒ»¸ö³ÌÐòÖУ¬×Ö¶Î a ºÍ×Ö¶Î b ´¦ÓÚͬһ¸ö Cache
Line ÉÏ£¬µ±Á½¸öÏß³ÌͬʱÐÞ¸ÄÕâÁ½¸ö×Ö¶Îʱ£¬»á´¥·¢ Cache Line α¹²ÏíÎÊÌ⣬Ôì³É´óÁ¿µÄ
Cache miss£¬½ø¶øµ¼Ö³ÌÐòÐÔÄÜϽµ¡£
µÚ¶þ¸ö³ÌÐòÖУ¬×Ö¶Î a ºÍ b Öмä¼ÓÁËÒ»¸ö 64 ×Ö½ÚµÄÊý×飬ÕâÑù¾Í±£Ö¤ÁËÕâÁ½¸ö×ֶδ¦ÔÚ²»Í¬µÄ
Cache Line ÉÏ¡£Èç´ËÒ»À´£¬Á½¸öÏ̼߳´±ãͬʱÐÞ¸ÄÕâÁ½¸ö×ֶΣ¬Á½¸ö cache line Ò²»¥²»Ó°Ï죬cache
ÃüÖÐÂʺܸߣ¬³ÌÐòÐÔÄÜ»á´ó·ùÌáÉý¡£
ʾÀý 5£¬(C ÓïÑÔ)
ÔÚÉè¼ÆÊý¾Ý½á¹¹µÄʱºò£¬¾¡Á¿½«Ö»¶ÁÊý¾ÝÓë¶ÁдÊý¾Ý·Ö¿ª£¬²¢¾ß¾¡Á¿½«Í¬Ò»Ê±¼ä·ÃÎʵÄÊý¾Ý×éºÏÔÚÒ»Æð¡£ÕâÑù
CPU ÄÜÒ»´Î½«ÐèÒªµÄÊý¾Ý¶ÁÈ롣ƩÈ磬ÏÂÃæµÄÊý¾Ý½á¹¹¾ÍºÜ²»ºÃ¡£
struct __a
{
int id; // ²»Ò×±ä
int factor;// Ò×±ä
char name[64];// ²»Ò×±ä
int value;// Ò×±ä
};
|
ÔÚ X86 Ï£¬¿ÉÒÔÊÔ×ÅÐ޸ĺ͵÷ÕûËü
#define CACHE_LINE_SIZE
64 //»º´æÐ㤶È
struct __a
{
int id; // ²»Ò×±ä
char name[64];// ²»Ò×±ä
char __align[CACHE_LINE_SIZE ¨C sizeof(int)+sizeof(name)
* sizeof(name[0]) %
CACHE_LINE_SIZE]
int factor;// Ò×±ä
int value;// Ò×±ä char __align2 [CACHE_LINE_SIZE
¨C2* sizeof(int)%CACHE_LINE_SIZE ]}; |
CACHE_LINE_SIZE¨Csizeof(int)+sizeof
(name)*sizeof (name[0])%CACHE_LINE_SIZE ¿´ÆðÀ´²»ºÍг£¬CACHE_LINE_SIZE
±íʾ¸ßËÙ»º´æÐÐ(64B ´óС)¡£__align ÓÃÓÚÏÔʽ¶ÔÆë£¬ÕâÖÖ·½Ê½Ê¹µÃ½á¹¹Ìå×Ö½Ú¶ÔÆëµÄ´óСΪ»º´æÐеĴóС¡£
4.4 »º´æÓëÄÚ´æ¶ÔÆë
1£©×Ö½Ú¶ÔÆë
attribute ((packed))¸æËß±àÒëÆ÷È¡Ïû½á¹¹ÔÚ±àÒë¹ý³ÌÖеÄÓÅ»¯¶ÔÆë,°´ÕÕʵ¼ÊÕ¼ÓÃ×Ö½ÚÊý½øÐÐ¶ÔÆë£¬ÊÇ
GCC ÌØÓеÄÓï·¨;
__attribute__((aligned(n)))±íʾËù¶¨ÒåµÄ±äÁ¿Îª n ×Ö½Ú¶ÔÆë;
struct B{ char b;int a;short c;}; (ĬÈÏ 4 ×Ö½Ú¶ÔÆë)
ÕâʱºòͬÑùÊÇ×ܹ² 7 ¸ö×ֽڵıäÁ¿£¬µ«ÊÇ sizeof(struct B)µÄֵȴÊÇ 12¡£
×Ö½Ú¶ÔÆëµÄϸ½ÚºÍ±àÒëÆ÷ʵÏÖÏà¹Ø£¬µ«Ò»°ã¶øÑÔ£¬Âú×ãÈý¸ö×¼Ôò£º
1)(½á¹¹Ìå)±äÁ¿µÄÊ×µØÖ·Äܹ»±»Æä(×î¿í)»ù±¾ÀàÐͳÉÔ±µÄ´óСËùÕû³ý£»
2)½á¹¹Ìåÿ¸ö³ÉÔ±Ïà¶ÔÓÚÊ×µØÖ·µÄÆ«ÒÆÁ¿¶¼ÊdzÉÔ±´óСµÄÊý±¶£¬ÈçÓÐÐèÒª,±àÒëÆ÷»áÔÚ³ÉÔ±Ö®¼ä¼ÓÉÏÌî³ä×Ö½Ú(internal
adding)
3)½á¹¹ÌåµÄ×Ü´óСΪ½á¹¹Ìå×î¿í»ù±¾ÀàÐͳÉÔ±´óСµÄÊý±¶£¬ÈçÓÐÐèÒª,±àÒëÆ÷»áÔÚ×îĩһ¸ö³ÉÔ±Ö®ºó¼ÓÉÏÌî³ä×Ö½Ú(trailing
padding)
2£©»º´æÐÐ¶ÔÆë
Êý¾Ý¿çÔ½Á½¸ö cache line£¬Òâζ×ÅÁ½´Î load »òÁ½´Î store¡£Èç¹ûÊý¾Ý½á¹¹ÊÇ cache
line ¶ÔÆëµÄ£¬¾ÍÓпÉÄܼõÉÙÒ»´Î¶Áд¡£Êý¾Ý½á¹¹µÄÊ×µØÖ· cache line ¶ÔÆë£¬Òâζ×Å¿ÉÄÜÓÐÄÚ´æÀË·Ñ(ÌØ±ðÊÇÊý×éÕâÑùÁ¬Ðø·ÖÅäµÄÊý¾Ý½á¹¹£©£¬ËùÒÔÐèÒªÔÚ¿Õ¼äºÍʱ¼äÁ½·½ÃæÈ¨ºâ¡£±ÈÈçÏÖÔÚÒ»°ãµÄ
malloc()º¯Êý£¬·µ»ØµÄÄÚ´æµØÖ·»áÒѾÊÇ 8 ×Ö½Ú¶ÔÆëµÄ£¬Õâ¾ÍÊÇΪÁËÄܹ»Èô󲿷ֳÌÐòÓиüºÃµÄÐÔÄÜ¡£
ÔÚ C ÓïÑÔÖУ¬ÎªÁ˱ÜÃâα¹²Ïí£¬±àÒëÆ÷»á×Ô¶¯½«½á¹¹Ì壬×Ö½Ú²¹È«ºÍ¶ÔÆë£¬¶ÔÆëµÄ´óС×îºÃÊÇ»º´æÐеij¤¶È¡£×ܵÄÀ´Ëµ£¬½á¹¹ÌåʵÀý»áºÍËüµÄ×î¿í³ÉÔ±Ò»Ñù¶ÔÆë¡£±àÒëÆ÷ÕâÑù×öÊÇÒòΪÕâÊDZ£Ö¤ËùÓгÉÔ±×Ô¶ÔÆëÒÔ»ñµÃ¿ìËÙ´æÈ¡µÄ×îÈÝÒ×·½·¨¡£
__attribute__((aligned(cache_line)))¶ÔÆëʵÏÖ struct syn_str
{ ints_variable;
};__attribute__((aligned(cache_line)))£»
ʾÀý 6£¬(C ÓïÑÔ)
struct
syn_str { int s_variable; };void
*p = malloc ( sizeof (struct syn_str) + cache_line
);syn_str
*align_p=(syn_str*)((((int)p)+ (cache_line-1))&~(cache_line-1); |
4.5 CPU ·ÖÖ§Ô¤²â
´úÂëÔÚÄÚ´æÀïÃæÊÇ˳ÐòÅÅÁеģ¬¿ÉÒÔ˳Ðò·ÃÎÊ£¬ÓÐЧÌá¸ß»º´æÃüÖС£¶ÔÓÚ·ÖÖ§³ÌÐòÀ´Ëµ£¬Èç¹û·ÖÖ§Óï¾äÖ®ºóµÄ´úÂëÓиü´óµÄÖ´Ðм¸ÂÊ£¬¾Í¿ÉÒÔ¼õÉÙÌø×ª£¬Ò»°ã
CPU ¶¼ÓÐÖ¸ÁîԤȡ¹¦ÄÜ£¬ÕâÑù¿ÉÒÔÌá¸ßÖ¸ÁîԤȡÃüÖеļ¸ÂÊ¡£·ÖÖ§Ô¤²âÓõľÍÊÇ likely/unlikely
ÕâÑùµÄºê£¬Ò»°ãÐèÒª±àÒëÆ÷µÄÖ§³Ö£¬Êô¾²Ì¬µÄ·ÖÖ§Ô¤²â¡£ÏÖÔÚÒ²Óкܶà CPU Ö§³ÖÔÚÄÚ²¿±£´æÖ´ÐйýµÄ·ÖÖ§Ö¸ÁîµÄ½á¹û(·ÖÖ§Ö¸Áî
cache)£¬ËùÒÔ¾²Ì¬µÄ·ÖÖ§Ô¤²â¾ÍûÓÐÌ«¶àµÄÒâÒå¡£
ʾÀý 7£¬(C ÓïÑÔ)
int
testfun(int x)
{
if(__builtin_expect(x, 0)) {
^^^--- We instruct the compiler , "else"
block
is more probable
x = 5;
x = x * x;
} else {
x = 6;
}
return x;
}` |
ÔÚÕâ¸öÀý×ÓÖУ¬x Ϊ 0 µÄ¿ÉÄÜÐÔ¸ü´ó£¬±àÒëºó¹Û²ì»ã±àÖ¸Á½á¹ûÈçÏ£º
`Disassembly
of section .text£º
00000000 <testfun>:
0: 55 push %ebp
1: 89e5 mov %esp,%ebp
3: 8b 45 08 mov 0x8(%ebp),%eax
6: 85 c0 test %eax,%eax
8: 75 07 jne 11 <testfun+0x11>
a: b8 06 00 00 00 mov $0x6,%eax
f: c9 leave
10: c3 ret
11: b8 19 00 00 00 mov $0x19,%eax
16: eb f7 jmp f <testfun+0xf>` |
¿ÉÒÔ¿´µ½£¬±àÒëÆ÷ʹÓõÄÊÇ jne Ö¸ÁÇÒ else block
ÖеĴúÂë½ô¸úÔÚºóÃæ
8: 75 07 jne
11 < testfun+0x11>
a: b8 06 00 00 00 mov $0x6,%eax |
4.6 ÃüÖÐÂÊµÄ¼à¿Ø
³ÌÐòÉè¼ÆÒª×·Çó¸üºÃµÄÀûÓà CPU »º´æ£¬À´¼õÉÙ´ÓÄÚ´æ¶ÁÈ¡Êý¾ÝµÄµÍЧ¡£ÔÚ³ÌÐòÔËÐÐʱ£¬Í¨³£ÐèÒª¹Ø×¢»º´æÃüÖÐÂÊÕâ¸öÖ¸±ê¡£
¼à¿Ø·½·¨(Linux)£º²éѯ CPU »º´æÎÞÃüÖдÎÊý¼°»º´æÇëÇó´ÎÊý£¬¼ÆË㻺´æÃüÖÐÂÊ
perf stat -e
cache- references -e cache-misses |
4.7 С ½á
³ÌÐò´ÓÄÚ´æ»ñÈ¡Êý¾Ýʱ£¬Ã¿´Î²»½öÈ¡»ØËùÐèÊý¾Ý£¬»¹»á¸ù¾Ý»º´æÐеĴóС¼ÓÔØÒ»¶ÎÁ¬ÐøµÄÄÚ´æÊý¾Ýµ½»º´æÖУ¬³ÌÐòÉè¼ÆÖеÄÓÅ»¯·¶Ê½²Î¿¼ÈçÏ¡£
ÔÚ¼¯ºÏ±éÀúµÄ³¡¾°£¬¿ÉʹÓÃÓÐÐòÊý×飬Êý×éÔÚÄÚ´æÖÐÊÇÒ»¶ÎÁ¬ÐøµÄ¿Õ¼ä;
×ֶξ¡Á¿¶¨ÒåΪռÓÃ×Ö½ÚСµÄÀàÐÍ£¬Èç int ¿ÉÂú×ãʱ£¬²»Ê¹Óà long¡£ÕâÑùµ¥´Î¿É¼ÓÔØ¸ü¶àµÄÊý¾Ýµ½»º´æÖÐ;
¶ÔÏó»ò½á¹¹Ìå´óС¾¡¿ÉÄÜÉèÖÃΪ CPU ºËÐÄ»º´æÐеÄÕûÊý±¶¡£»ùÓÚ 64B
´óСµÄ»º´æÐУ¬Èç¶ÁÈ¡µÄÊý¾ÝÊÇ 50B£¬×Çé¿öÏÂÐèÒªÁ½´Î´ÓÄÚ´æ¼ÓÔØ£»µ±Îª 70B ʱ£¬×Çé¿öÐèÒªÈý´ÎÄÚ´æ¶ÁÈ¡£¬²ÅÄܼÓÔØµ½»º´æÖÐ;
¶Ôͬһ¶ÔÏó/½á¹¹ÌåµÄ¶à¸öÊôÐÔ£¬¿ÉÄÜ´æÔÚÓÚͬһ»º´æÐÐÖУ¬µ¼ÖÂα¹²ÏíÎÊÌ⣬ÐèΪÊôÐԵIJ»±äÓë³£±ä£¬±ä»¯µÄ¶ÀÁ¢Óë¹ØÁª¶ø¸ôÀëÉè¼Æ£¬¼°»º´æÐÐ¶ÔÆë£¬½â¾ö¶àÏ̸߲߳¢·¢»·¾³Ï»º´æÊ§Ð§¡¢±Ë´ËÇ£ÖÆÎÊÌ⣻
CPU ÓзÖÖ§Ô¤²âÄÜÁ¦£¬ÔÚʹÓà ifelse case when
µÈÑ»·Åжϵij¡¾°Ê±£¬¿ÉÒÔ˳Ðò·ÃÎÊ£¬ÓÐЧÌá¸ß»º´æµÄÃüÖÐ |