水平求和 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 位)位进行最终水平求和) 最后将标量减半。
我需要水平添加一个 __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 位)位进行最终水平求和) 最后将标量减半。