c++ sum sse simd reduction

c++ - Reducción de SSE del vector flotante



sum simd (1)

Normalmente, se generan 4 sumas parciales en el ciclo y luego se suman horizontalmente a través de los 4 elementos después del ciclo, por ejemplo

#include <cassert> #include <cstdint> #include <emmintrin.h> float vsum(const float *a, int n) { float sum; __m128 vsum = _mm_set1_ps(0.0f); assert((n & 3) == 0); assert(((uintptr_t)a & 15) == 0); for (int i = 0; i < n; i += 4) { __m128 v = _mm_load_ps(&a[i]); vsum = _mm_add_ps(vsum, v); } vsum = _mm_hadd_ps(vsum, vsum); vsum = _mm_hadd_ps(vsum, vsum); _mm_store_ss(&sum, vsum); return sum; }

Nota: para el ejemplo anterior, a debe estar alineado 16 bytes y n debe ser un múltiplo de 4. Si no se puede garantizar la alineación de a , utilice _mm_loadu_ps lugar de _mm_load_ps . Si n no garantiza que sea un múltiplo de 4, entonces agregue un bucle escalar al final de la función para acumular los elementos restantes.

¿Cómo puedo obtener elementos suma (reducción) del vector flotante usando intrínsecos sse?

Código de serie simple:

void(float *input, float &result, unsigned int NumElems) { result = 0; for(auto i=0; i<NumElems; ++i) result += input[i]; }