如何解决缓存阻止实际上如何提高性能?
我正在阅读有关this intel page上的缓存阻止的信息。
它说:
阻塞是一种众所周知的优化技术,可以帮助避免许多应用程序中的内存带宽瓶颈。阻止背后的关键思想是通过确保数据在多次使用中都保留在缓存中来利用应用程序中固有的数据重用。
提供示例
for (body1 = 0; body1 < NBODIES; body1 ++) { for (body2=0; body2 < NBODIES; body2++) { OUT[body1] += compute(body1,body2); } }
在此示例中,数据(body2)从内存中流式传输。假设NBODIES很大,我们将不会在缓存中重用。此应用程序受内存带宽限制。该应用程序将以内存到CPU的速度运行,而不是最佳速度。
优化为
for (body2 = 0; body2 < NBODIES; body2 += BLOCK) { for (body1=0; body1 < NBODIES; body1 ++) { for (body22=0; body22 < BLOCK; body22 ++) { OUT[body1] += compute(body1,body2 + body22); } } }
通过将body2循环拆分为一个在BLOCK的多个主体上进行迭代的外部循环,以及将body2循环在该块内的元素上进行迭代的一个内部body22循环,并将body1和body2循环进行交织,即可获得阻塞代码...。此代码在body1循环的多次迭代中重用了一组BLOCK body2值。如果选择BLOCK以使这组值适合高速缓存,则内存流量将减少BLOCK。
老实说,我不理解随附的解释。
我也不了解如何减少内存流量,以及为什么被阻止的示例会更快。
请有人帮忙解释一下缓存阻塞及其如何加速循环吗?
Wikipedia同样有一个示例:
可以通过将for (i=0; i<N; ++i) { ... }
替换为块大小B来对其进行阻止
for (j=0; j<N; j+=B) { for (i=j; i<min(N,j+B); ++i) { .... } }
我不知道为什么这样做会更快。
为什么要利用缓存?
解决方法
该英特尔论文是不好的,因为它没有弄清楚索引body2
与数据在内存中的位置之间的关联或body1
与内存中的数据之间的关联。这个想法是OUT[body1]
将使用来自同一缓存块的多个元素来获取body1
的多个连续值。但是,body1
的连续值的使用不会一个接一个地发生。它们之所以散布是因为body2
上的整个循环是在它们之间执行的。大概,使用compute(body1,body2)
会导致根据body2
值使用各种内存。
概念是,在body2
循环过程中,将访问内存中的许多不同位置,从而与OUT[body1]
关联的缓存块将从缓存中逐出,因此,当{ {1}}递增到下一个值,但是body1
仍将位于同一缓存块中,该块不再位于缓存中,必须再次加载。这样很浪费。
将源代码更改为:
OUT[body1]
通过在更改for (body2 = 0; body2 < NBODIES; body2 += BLOCK) {
for (body1=0; body1 < NBODIES; body1 ++) {
for (body22=0; body22 < BLOCK; body22 ++) {
OUT[body1] += compute(body1,body2 + body22);
}}
// Note: A closing "}" is missing in the original.
之前处理更少的compute(body1,something)
实例来解决该问题。如果body1
设置得足够小,则与BLOCK
关联的缓存块仍在缓存中,不需要从内存中重新加载。因此,在内循环中:
OUT[body1]
for (body1=0; body1 < NBODIES; body1 ++) {
for (body22=0; body22 < BLOCK; body22 ++) {
OUT[body1] += compute(body1,body2 + body22);
}}
的每个缓存块仅从内存中加载一次并写入一次。
当然,这些内部循环位于OUT[body1]
上的新外部循环内部,因此,内部循环将执行body2
次(本文忽略了如果NBODIES/BLOCK
为NOBODIES
不能完全整除,我也将),因此BLOCK
的缓存块仍必须重新加载OUT[body1]
次,但这比重新加载NBODIES/BLOCK
更好时间,发生在原始代码中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。