数组上的迭代方向

时间:2014-07-21 06:35:34

标签: c++ arrays cpu-cache

假设我们有两个基本类型的数组ab(例如,float),我们需要为每个有效索引{{1}计算a[i] + b[i] ,以及存储结果。迭代数组以最大化缓存命中的最佳方法是什么?它是从前到后,从前到后还是其他什么东西?

2 个答案:

答案 0 :(得分:1)

为了利用缓存预取功能,您需要按顺序从前到后读取数组。

此外,阵列应该是SSE对齐的(16字节)。更重要的是项目(例如浮点数)将按其大小对齐(浮点数为4个字节)。这很重要,因此数据不会跨越缓存行(读取速度较慢)。

阵列对齐后,您可以使用SSE / AVX读取,添加和存储结果,在一条指令中执行4或8次操作。

修改 您可以在here中详细了解缓存预取Intel SW Developer Manual和深度说明。

答案 1 :(得分:1)

对于这种操作,您应该使用编译器的自动矢量化。将小i迭代为大i。此外,答案取决于“存储结果”的含义以及要迭代的项目项目的数量n

如果您的意思是c[i] = a[i] + b[i]n不是太小,那么编译器的自动矢量化程序将优化这一点而不需要进行任何更改。甚至MSVC也会得到正确的(至少对于SSE而言)。您的编译器必须对n进行一些调整,而不是4的倍数(或AVX的8)和对齐,但是这个成本将在n中摊销,除了小n之外,这种开销将产生微不足道的影响。如果n很小,那么您可能需要考虑对齐。有多小是必须确定的,但我猜它远远小于100.

如果你的意思是sum + = a[i] + b[i],减少,那么你需要考虑这个问题。这有一个依赖关系链,因此您需要展开循环3-10 times。此外,您需要使用自floating point arithmetic is not associative and the auto-vectorization won't kick in without it以来的宽松浮点模型,因此将-ffast-math添加到GCC(/fp:fast到MSVC)。如果您展开循环并使用宽松的浮点模型,那么GCC,ICC,Clang和MSVC应该有效地自动矢量化您的缩减。