x86 – 使用AVX指令执行水平矢量和的最快方法

我有一个包含四个64位浮点值的压缩向量.
我想得到矢量元素的总和.

使用SSE(并使用32位浮点数),我可以执行以下操作:

v_sum = _mm_hadd_ps(v_sum, v_sum);
v_sum = _mm_hadd_ps(v_sum, v_sum);

不幸的是,虽然AVX具有_mm256_hadd_pd指令,但SSE版本的结果却不尽相同.我相信这是因为大多数AVX指令分别作为每个低和高128位的SSE指令,而不会跨越128位边界.

理想情况下,我正在寻找的解决方案应遵循以下准则:
1)仅使用AVX / AVX2指令. (无SSE)
2)不要超过2-3个说明.

然而,任何高效/优雅的方式(即使没有遵循上述指导原则)总是被广泛接受.

非常感谢任何帮助.

-Ligig Castelli

如果您有两个__m256d向量x1和x2,每个向量x1和x2都包含要双向叠加的四个双精度,则可以执行以下操作:

__m256d x1, x2;
// calculate 4 two-element horizontal sums:
// lower 64 bits contain x1[0] + x1[1]
// next 64 bits contain x2[0] + x2[1]
// next 64 bits contain x1[2] + x1[3]
// next 64 bits contain x2[2] + x2[3]
__m256d sum = _mm256_hadd_pd(x1, x2);
// extract upper 128 bits of result
__m128d sum_high = _mm256_extractf128_pd(sum1, 1);
// add upper 128 bits of sum to its lower 128 bits
__m128d result = _mm_add_pd(sum_high, _mm256_castpd256_pd128(sum));
// lower 64 bits of result contain the sum of x1[0], x1[1], x1[2], x1[3]
// upper 64 bits of result contain the sum of x2[0], x2[1], x2[2], x2[3]

所以看起来3个指令会做出你需要的两个水平总和.以上是未经测试的,但您应该得到这个概念.

翻译自:https://stackoverflow.com/questions/9775538/fastest-way-to-do-horizontal-vector-sum-with-avx-instructions

转载注明原文:x86 – 使用AVX指令执行水平矢量和的最快方法