首页 > 代码库 > [原理分析]多核下的缓存块伪共享问题
[原理分析]多核下的缓存块伪共享问题
摘要:
本文主要介绍多核下的缓存块伪共享问题,该问题的存在可能导致的有趣现象:两个核跑一个程序,不如单个核跑该程序来得快。
正文:
1.本文考虑的处理器中每个核私有L1缓存,并且多个核共享L2缓存;L1和L2缓存中的缓存块大小都为64bytes,认为double数据类型在本机器上需要8bytes来表示;
2. 缓存一致性的协议:本文考虑的缓存一致性是基于监听(snoop)的写无效(write invalidate)策略,给个简单的例子来说明该策略:当core 0和core 1读访问L2中的缓存块A时,那么在core0和core1中同时存在缓存块A的两个拷贝;当core0写L1中的缓存块A拷贝时,并且在总线上发消息说:自己修改了A缓存块;那么core1接受到该消息时,就知道自己L1中的缓存块A拷贝不是最新,此时core1就会将自己的缓存块A拷贝置为无效;当core1再次要访问该缓存块时,由于发现无效,就会从外部(比如从core0的L1缓存)读取最新的拷贝。上述的缓存一致性策略就是基于监听的写无效策略。
3. 下面是本文要考虑的程序:
int i, j, m, n; double y[m]; for(int i=0; i<m; i++) for(int j=0; j<n; j++) y[i]+=f(i, j);我们修改上述的代码,使得其可以在两个core上并行执行,修改后的代码中core_count设置为2,具体如下:
int i, j, iter_count; int m, n, core_count; double y[m]; iter_count = m/core_count; //so core 0 does this for(i=0; i<iter_count; i++) for(j=0; j<n; j++) y[i]+=f(i,j); //so core 1 does this; for(i=iter_count; i<2*iter_count; i++) for(j=0; j<n; j++) y[i]+=f(i, j);假设这里的m=8, 一个缓存块的大小为64bytes, 并且一个double需要8个bytes,这样的情况下,所有的y数组元素刚好占用一个缓存块:其中的y[0-3]元素(缓存块前半段)由core0写访问;而其中的y[4-7]数组元素(缓存块后半段)由core1写访问。虽然每个core上运行的代码只对属于自己的那部分y进行操作,但是由于缓存块在core0和core1中都有拷贝;所以产生的现象是每次一个core对自己那部分的y值进行操作时,另外一个core上的缓存拷贝就会被invalid,造成需要重新读取该cache line的情况;因为这里的两个core其实都不会用到对方的数据,但是实际运行中却会相互影响,使得对方的缓存拷贝无效化,对方要用到该缓存拷贝中的数据时,又需要重新进行读取;由于读取缓存块的时间极大地滞后于处理器计算的速度,因此上述的伪共享会极大影响系统性能:造成两个核的处理速度,不如一个核。
结束语:
本文主要介绍多核下的缓存块伪共享问题,该问题的存在可能导致的有趣现象:两个核跑一个程序,不如单个核跑该程序来得快。
[原理分析]多核下的缓存块伪共享问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。