1. 伪共享产生:
在SMP架构的系统中,每个CPU核心都有自己的cache,当多个线程在不同的核心上,并且某线程修改了在同一个cache line中的数据时,由于cache一致性原则,其他核心cache中相同cache line会失效,从而产生cache miss,并重新从内存中读入数据到cache line,显然,这样多核心并没有实现真正的共享,称之为伪共享。
如下图:cpu0,cpu1中的Thread0和Thread1访问统一cache line中的不同数据,此时如果Thread1修改了cache line中块1的数据,则cpu0中的cache line同样也会失效,这时当Thread0读取cache line中的块0的数据时,就会产生cache miss,并更新cache line;
2. 测试:
1. 查看cacheline对齐字节数;
cat /proc/cpuinfo cache_alignment : 64
2. 测试代码:
#include <stdio.h> #include <pthread.h> #define CACHE_LINE 64 struct num { //使用attribute设置cacheline对齐 int number __attribute__ ((aligned(CACHE_LINE))); //或者使用padding对cacheline进行补齐 //char padding[CACHE_LINE-sizeof(int)]; }; struct num arr_num[2]; void *thread0(void *params) { arr_num[0].number = 0; for (unsigned int i = 0; i < (unsigned int)-1; i++) { arr_num[0].number++; } } void *thread1(void *params) { arr_num[1].number = 0; for (unsigned int i = 0; i < (unsigned int)-1; i++) { arr_num[1].number++; } } int main() { pthread_t tid[2]; pthread_create(&tid[0], NULL, thread0, NULL); pthread_create(&tid[1], NULL, thread1, NULL); pthread_join(tid[0], NULL); pthread_join(tid[1], NULL); return 0; }
测试结果对比:
不使用cacheline对齐或者补齐
wanpengcoderMac-mini:~ Alex$ time ./false_sharing real 0m34.645s user 1m8.875s sys 0m0.079s
使用cacheline对齐或者补齐
wanpengcoderMac-mini:~ Alex$ time ./false_sharing real 0m10.193s user 0m20.236s sys 0m0.026s