假设我们有两个基本类型的数组 a
和 b
(比如 float
),我们需要计算 a[i] + b[i]
为每个有效索引 i
,并存储结果。迭代数组以最大化缓存命中率的最佳方法是什么?是从前到后、从后到前还是其他?
最佳答案
对于这种操作,您应该使用编译器的自动矢量化。将小的 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 应该可以有效地自动矢量化您的缩减。
关于c++ - 数组的迭代方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24858948/