c++ - 水平求和 SSE 无符号字节 vector 的最快方法

标签 c++ x86 sse simd

我需要水平添加一个 __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);
}

如果您要对多个字节 vector 求和,请在 vsum 结果上使用 _mm_add_epi32(或 64),只对两个 32 (或 64 位)最后减半到标量一次。

关于c++ - 水平求和 SSE 无符号字节 vector 的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36998538/

相关文章:

c++ - "New"实现与 vtk 和子类

c++ - 将 char 指针传递给另一个函数 : blank value. c++

c - _mm_testc_ps 和 _mm_testc_pd 与 _mm_testc_si128

assembly - 将 XMM 寄存器设置为重复字节模式(广播常量字节)

c++ - 在增量循环的情况下如何使用 SSE?

c++ - 为什么 std::inner_product 比原始实现慢?

c++ - 带有非典型比较器的 std::map 的奇怪行为

c# - 无法将 C# 代码移植到实现 IDataErrorInfo 的托管 C++

x86 - .com 可执行文件可以在 Windows 以外的其他操作系统上运行吗?

loops - 如果我在循环中使用 ECX(汇编),正确的循环方法是什么