CPU Cache原理与示例 (5)

然而,在执行过程中,会发现,6 个线程居然跑不过 1 个线程。因为根据上面的例子知道 result[]数组中的数据在一个 Cache Line 中,所以,所有的线程都会对这个 Cache Line 进行写操作,导致所有的线程都在不断地重新同步result[] 所在的 Cache Line,所以,导致 6 个线程还跑不过一个线程的结果。这叫False Sharing

优化也很简单,使用一个线程内的变量。

void thread_func (int id)

{

result[id] = 0;

int chunk_size = total_size / nthread + 1;

int start = id * chunk_size;

int end = min(start + chunk_size, total_size);

int c = 0; //使用临时变量,没有cache line的同步了

for ( int i = start; i < end; ++i )

{

if (test_data[i] % 2 != 0 ) ++c;

}

result[id] = c;

}

把两个程序分别在 1 到 32 个线程上跑一下,得出的结果画一张图如下所示(横轴是线程数,纵轴是完成统的时间,单位是微秒):

CPU Cache原理与示例

上图中,可以看到,灰色的曲线就是第一种方法,橙色的就是第二种(用局部变量的)方法。当只有一个线程的时候,两个方法相当,基本没有什么差别,但是在线程数增加时,会发现,第二种方法的性能提高的非常快。直到到达 6 个线程的时候,开始变得稳定(前面说过,CPU 是6核的)。

第一种方法无论加多少线程也没有办法超过第二种方法。因为第一种方法不是 CPU Cache 友好的。也就是说,第二种方法,只要 CPU 核数足够多,就可以做到线性的性能扩展,让每一个 CPU 核都跑起来,第一种则不能


参考链接:

https://zhuanlan.zhihu.com/p/445961133

https://mp.weixin.qq.com/s/s9w--YRkyAvQi4LQcenq4g

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgypyx.html