【问题标题】:Memory benchmark plot: understanding cache behaviour内存基准图:了解缓存行为
【发布时间】:2013-12-24 09:53:12
【问题描述】:

我已经尝试了所有可能得出的推理,但我并不真正理解这个情节。 它基本上显示了从不同大小的数组以不同的步幅读取和写入的性能。 我知道对于像 4 字节这样的小步幅,我读取了缓存中的所有单元格,因此我有很好的性能。但是当我有 2 MB 数组和 4k 步幅时会发生什么?还是 4M 和 4k 步幅?为什么性能这么差?最后,为什么当我有 1MB 阵列并且步幅为 1/8 大小时性能还不错,什么时候 1/4 大小性能最差,然后在一半大小时,性能超级好? 请帮帮我,这件事快把我逼疯了。

在此链接,代码:https://dl.dropboxusercontent.com/u/18373264/membench/membench.c

【问题讨论】:

标签: performance memory benchmarking


【解决方案1】:

您的代码在给定的时间间隔内循环而不是恒定的访问次数,您没有比较相同的工作量,并且并非所有缓存大小/步长都享有相同的重复次数(因此它们获得不同的缓存机会)。

另外请注意,第二个循环可能会被优化掉(内部的for),因为您不会在任何地方使用temp

编辑:

这里的另一个影响是 TLB 利用率:

在 4k 页面系统上,当您的步幅仍小于 4k 时,您会越来越少地使用每个页面(最终在 4k 步幅上达到每页一次访问),这意味着访问时间会增加因为您必须在每次访问时访问第二级 TLB(甚至可能序列化您的访问,至少部分)。
由于您通过步幅大小对迭代计数进行标准化,因此您通常在最内层循环中有 (size / stride) 访问,但在外面有 * stride 访问。但是,您访问的唯一页面数量不同 - 对于 2M 数组,2k 步幅,您在内循环中有 1024 次访问,但只有 512 个唯一页面,因此对 TLB L2 的访问次数为 512*2k。在 4k 步长上,仍有 512 个唯一页面,但有 512*4k TLB L2 访问。
对于 1M 数组的情况,您总共将有 256 个唯一页面,因此 2k 步长将有 256 * 2k TLB L2 访问,而 4k 将再次有两次。

这解释了为什么当您接近 4k 时每条线的性能会逐渐下降,以及为什么数组大小每次翻倍都会使相同步幅的时间翻倍。较低的阵列大小可能仍部分享受 L1 TLB,因此您看不到相同的效果(尽管我不确定为什么会有 512k)。

现在,一旦您开始将步幅提高到 4k 以上,您就会突然再次受益,因为您实际上是在跳过整页。 8K 步长将仅访问每隔一个页面,对于相同的数组大小,将总 TLB 访问的一半作为 4k,依此类推。

【讨论】:

  • 这不是我自己写的代码,但是根据那个代码你能回答我的疑问吗?
  • @DavideNava,添加了另一个效果,我相信可以解释您在此处看到的行为
猜你喜欢
  • 2015-04-23
  • 2020-08-03
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多