horizontal sum of 8 packed 32bit floats
avx, simd, sse, x86
Solution
Quickly jotted down here (and hence untested):
float sum(__m256 x) {
__m128 hi = _mm256_extractf128_ps(x, 1);
__m128 lo = _mm256_extractf128_ps(x, 0);
lo = _mm_add_ps(hi, lo);
hi = _mm_movehl_ps(hi, lo);
lo = _mm_add_ps(hi, lo);
hi = _mm_shuffle_ps(lo, lo, 1);
lo = _mm_add_ss(hi, lo);
return _mm_cvtss_f32(lo);
}
For min/max, replace `_mm_add_ps` and `_mm_add_ss` with `_mm_max_*` or `_mm_min_*`.
Note that this is a lot of work for a few operations; AVX isn't really intended to do horizontal operations efficiently. If you can batch up this work for multiple vectors, then more efficient solutions are possible.
Problem
If I have 8 packed 32-bit floating point numbers (`__m256`), what's the fastest way to extract the horizontal sum of all 8 elements? Similarly, how to obtain the horizontal maximum and minimum? In other words, what's the best implementation for the following C++ functions? ``` float sum(__m256 x); ///< returns sum of all 8 elements float max(__m256 x); ///< returns the maximum of all 8 elements float min(__m256 x); ///< returns the minimum of all 8 elements ```