参考链接 https://stackoverflow.com/questions/16699247/what-is-a-cache-friendly-code
只是堆积:缓存不友好与缓存友好代码的典型例子是矩阵乘法的“缓存阻塞”。
朴素矩阵乘法看起来像
for(i=0;i<N;i++) { for(j=0;j<N;j++) { dest[i][j] = 0; for( k==;k<N;i++) { dest[i][j] += src1[i][k] * src2[k][j]; } } }
如果N
很大,例如,如果N * sizeof(elemType)
大于高速缓存大小,那么每次访问都src2[k][j]
将是高速缓存未命中。
有许多不同的方法可以为缓存优化它。这是一个非常简单的示例:不是在内部循环中每个缓存行读取一个项目,而是使用所有项目:
int itemsPerCacheLine = CacheLineSize / sizeof(elemType); for(i=0;i<N;i++) { for(j=0;j<N;j += itemsPerCacheLine ) { for(jj=0;jj<itemsPerCacheLine; jj+) { dest[i][j+jj] = 0; } for( k==;k<N;i++) { for(jj=0;jj<itemsPerCacheLine; jj+) { dest[i][j+jj] += src1[i][k] * src2[k][j+jj]; } } } }
如果高速缓存行大小为64字节,并且我们在32位(4字节)浮点数上运行,则每个高速缓存行有16个项目。通过这种简单的转换,缓存未命中的数量减少了大约16倍。
Fancier转换在2D图块上运行,针对多个缓存(L1,L2,TLB)进行优化,等等。
谷歌搜索“缓存阻塞”的一些结果:
http://stumptown.cc.gt.atl.ga.us/cse6230-hpcta-fa11/slides/11a-matmul-goto.pdf
http://software.intel.com/en-us/articles/cache-blocking-techniques
一个优化的缓存阻塞算法的精彩视频动画。
http://www.youtube.com/watch?v=IFWgwGMMrh0
循环平铺非常密切相关:
http://en.wikipedia.org/wiki/Loop_tiling
转载于:https://www.cnblogs.com/luoyinjie/p/10063432.html