水平求和 SSE 无符号字节向量的最快方法

Fastest way to horizontally sum SSE unsigned byte vector

我需要水平添加一个 __m128i,即 16 x epi8 值。 XOP 指令将使这变得微不足道,但我没有可用的指令。

当前方法是:

hd = _mm_hadd_epi16(_mm_cvtepi8_epi16(sum), _mm_cvtepi8_epi16(_mm_shuffle_epi8(sum, swap)));
hd = _mm_hadd_epi16(hd, hd);
hd = _mm_hadd_epi16(hd, hd);

SSE4.1以上有没有更好的方法?

您可以使用 SSE2 的 _mm_sad_epu8 (psadbw),例如:

inline uint32_t _mm_sum_epu8(const __m128i v)
{
    __m128i vsum = _mm_sad_epu8(v, _mm_setzero_si128());
    return _mm_cvtsi128_si32(vsum) + _mm_extract_epi16(vsum, 4);
}

如果您要对多个字节矢量求和,请在 vsum 结果上使用 _mm_add_epi32(或 64),只对两个 32(或 64 位)位进行最终水平求和) 最后将标量减半。