在页面边界访问数据时速度变慢吗?

时间:2019-07-05 22:59:49

标签: performance memory cpu-architecture cpu-cache row-buffer

(我的问题与计算机体系结构和性能理解有关。没有找到相关的论坛,因此将其作为一般问题发布在这里。)

我有一个C程序,用于访问在虚拟地址空间中相隔X个字节的存储字。例如for (int i=0;<some stop condition>;i+=X){array[i]=4;}

我用变化的X来衡量执行时间。有趣的是,当X2的力量并且大约是页面大小时,例如X=1024,2048,4096,8192...,我会发现性能大幅下降。但是,在X的所有其他值上,例如10231025上,并没有减速。性能结果如下图所示。

X axis is the value of <code>X</code> and Y-axis is execution time in milliseconds

我在多台个人计算机上测试了我的程序,所有这些计算机都在Intel CPU上运行带x86_64的Linux。

这种减速的原因可能是什么?我们已经尝试了在DRAM,L3缓存等中使用行缓冲区,但这似乎没有意义...

更新(7月11日)

我们在此处进行了一些测试,在原始代码中添加了NOP指令。而且减速仍然存在。否决了4k别名。冲突高速缓存未命中的原因更可能是这种情况。

1 个答案:

答案 0 :(得分:1)

这里有两件事:

这些影响中的一个或两个都可能是Why is there huge performance hit in 2048x2048 versus 2047x2047 array multiplication?

中的一个因素

另一个可能的因素是,硬件预取在物理页面边界处停止。 Why does the speed of memcpy() drop dramatically every 4KB?但是,将步幅从1024更改为1023并不能在很大程度上帮助您实现这一目标。 IvyBridge和更高版本中的“下一页”预取仅是TLB预取,而不是下一页中的数据。


我大部分都假定使用x86,但是缓存别名/冲突遗漏的东西通常适用。具有简单索引的集关联高速缓存普遍用于L1d高速缓存。 (或者在较旧的CPU上,直接映射,其中每个“集合”只有1个成员)。 4k别名可能大部分是特定于Intel的。

跨虚拟页面边界进行预取可能也是一个普遍问题。