在2d数组上的缓存不友好循环比缓存友好循环快
Cache unfriendly loop over 2d-array faster than cache friendly loop
为什么使用msvc++编译时版本1比版本2快?
版本1:for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k)
res1[i][j] += mat1[i][k] * mat2[k][j];
版本2:for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k)
res1[i][j] += mat1[i][k] * mat2[j][k];
(N = 1000;res1,mat1,mat2是双[N][N]数组)
版本2不应该更快,因为在循环中索引mat2[j][k]是缓存友好的(当从ram将mat2[j][k]加载到缓存mat2[j][k+1], mat2[j][k+2],…也会被加载,因为它们在相同的缓存线上))?
(如果我关闭编译器优化(使用:"#pragma optimize(", off)")版本2比版本1快,但代码运行得慢得多(显然))。
编辑:性能:(使用windows.h ==> QueryPerformanceCounter测量的时间)
与编译器优化:版本1:~493毫秒;版本2:954毫秒未经编译器优化:Version1: ~3868 ms;版本2:~2266 ms
通过优化,对于第一个版本,编译器可以明显地将内部的两个循环重新排序为:
for (int i = 0; i < N; ++i)
for (int k = 0; k < N; ++k)
for (int j = 0; j < N; ++j)
res1[i][j] += mat1[i][k] * mat2[k][j];
这将使第一个版本在缓存感知方面与第二个版本相似。
第一个版本快了一倍的原因,可能是缓存了它的第二项:mat1[i][k]
,因为它在做了上面的优化之后,在内部循环中没有改变。
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 有没有办法在缓存中保持空升压循环缓冲区的前端热
- 在紧密的物理和碰撞循环中进行缓存友好的内存访问
- 基于范围的 for 循环是否缓存容器表达式,或每次迭代重新计算它
- 用于写入的循环顺序缓存
- 在循环中使用av_read_frame缓存AVFrames只获得最后几帧
- 深度嵌套循环的缓存中毒问题
- 在2d数组上的缓存不友好循环比缓存友好循环快
- 为什么要在 levelDB 的缓存中使用 while 循环(函数 Resize)?
- 更短的循环,相同的覆盖范围,为什么我在 Visual Studio 2013 的 c++ 中获得更多的“最后一级缓存未命