【问题标题】:Fastest way to horizontally sum SSE unsigned byte vector水平求和 SSE 无符号字节向量的最快方法
【发布时间】:2016-08-28 04:02:32
【问题描述】:

我需要水平添加一个__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 有没有更好的方法?

【问题讨论】:

标签: c++ x86 sse simd


【解决方案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 位)半的最终水平总和进行一次标量结束。

【讨论】:

  • 编译器未能将_mm_extract_epi16(vsum, 0) 优化为movd - 他们没有意识到低位dword 的高2 字节将为0,因此他们实际上使用pextrw eax, xmm0, 0godbolt.org/z/TMb8rc1j4。改用_mm_cvtsi128_si32(vsum) 来保存随机播放uop。我为你解决了这个问题。
猜你喜欢
  • 2011-10-23
  • 2012-04-04
  • 2015-04-06
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
相关资源
最近更新 更多