这种效果对于二级高速缓存争用而言比一级高速缓存争用强得多的原因是,二级高速缓存无法预取超过一行。
我的问题与预取数据有关。
从他的评论中我推断出L1可以一次预取多个缓存行。它能预取多少个?
据我所知,尝试编写代码来预取数据(例如使用_mm_prefetch)很少有帮助。唯一我读过的例子是Prefetching Examples?,只有10%的改进(在某些机器上)。Agner后来解释了这一点:
原因是现代处理器通过乱序执行和先进的预测机制自动预取数据。现代微处理器能够自动为包含具有不同步长的多个流的常规访问模式预取数据。因此,如果数据访问可以按照固定步长的常规模式排列,则无需显式地预取数据。
那么CPU如何决定要预取哪些数据,是否有办法帮助CPU做出更好的预取选择(例如“具有固定步幅的常规模式”)?
编辑:根据Leeor的评论,让我补充我的问题并使其更加有趣。 为什么关键步幅对L2的影响要比对L1大得多?
编辑:我尝试使用为什么转置512x512的矩阵比转置513x513的矩阵慢得多?中的代码复制Agner Fog的表格。我在具有L1 32KB 8路、L2 256 KB 8路和L3 10MB 20路的Xeon E5 1620(常春藤桥)上以MSVC2013 64位发布模式运行了此代码。 L1的最大矩阵大小约为90x90,L3的最大矩阵大小为256x256,L3的最大矩阵大小为1619。
Matrix Size Average Time
64x64 0.004251 0.004472 0.004412 (three times)
65x65 0.004422 0.004442 0.004632 (three times)
128x128 0.0409
129x129 0.0169
256x256 0.219 //max L2 matrix size
257x257 0.0692
512x512 2.701
513x513 0.649
1024x1024 12.8
1025x1025 10.1
我在L1中没有看到任何性能损失,但L2明显存在关键步幅问题,可能也存在于L3中。我还不确定为什么L1没有出现问题。可能有其他背景(开销)源支配着L1的时间。