c++ - 如何使用SSE2实现8bit madd

标签 c++ video sse simd sse2

阅读官方英特尔 C++ 内在引用,

SSE 2有以下命令

__m128i _mm_madd_epi16(__m128i a, __m128i b)

将 a 中的 8 个有符号 16 位整数乘以 b 中的 8 个有符号 16 位整数。 将有符号 32 位整数结果两两相加,并打包 4 个有符号 32 位整数 结果。

SSE 3已经

__m128i _mm_maddubs_epi16 (__m128i a, __m128i b)

将有符号和无符号字节相乘,添加水平的有符号字对,打包 饱和的签名词。

由于我使用 8 位像素,并且我只能使用 SSE 2(旧架构是目标),所以我需要一个 8 位 madd 指令。 我将如何继续?

最佳答案

希望这能起作用 - 我这里没有编译器。但即使我错过了一些东西,你也应该了解总体思路。

编辑:感谢@Peter Cordes 指出_mm_setzero_si128 最好直接使用。

inline __m128i _mm_madd_epi8_SSE2(const __m128i & a, const __m128i & b)
{
    // a = 0x00 0x01 0xFE 0x04 ...
    // b = 0x00 0x02 0x80 0x84 ...

    // To extend signed 8-bit value, MSB has to be set to 0xFF
    __m128i sign_mask_a  = _mm_cmplt_epi8(a, _mm_setzero_si128());
    __m128i sign_mask_b  = _mm_cmplt_epi8(b, _mm_setzero_si128());

    // sign_mask_a = 0x00 0x00 0xFF 0x00 ...
    // sign_mask_b = 0x00 0x00 0xFF 0xFF ...

    // Unpack positives with 0x00, negatives with 0xFF
    __m128i a_epi16_l    = _mm_unpacklo_epi8(a, sign_mask_a);
    __m128i a_epi16_h    = _mm_unpackhi_epi8(a, sign_mask_a);
    __m128i b_epi16_l    = _mm_unpacklo_epi8(b, sign_mask_b);
    __m128i b_epi16_h    = _mm_unpackhi_epi8(b, sign_mask_b);

    // Here - valid 16-bit signed integers corresponding to the 8-bit input
    // a_epi16_l = 0x00 0x00 0x01 0x00 0xFE 0xFF 0x04 0x00 ... 

    // Get the a[i] * b[i] + a[i+1] * b[i+1] for both low and high parts
    __m128i madd_epi32_l = _mm_madd_epi16(a_epi16_l, b_epi16_l);
    __m128i madd_epi32_h = _mm_madd_epi16(a_epi16_h, b_epi16_h);

    // Now go back from 32-bit values to 16-bit values & signed saturate
    return _mm_packs_epi16(madd_epi32_l, madd_epi32_h);
}

关于c++ - 如何使用SSE2实现8bit madd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19957709/

相关文章:

video - 比特率非常低的视频编解码器?

c++ - 将 Ceres 与带有 sse/avx 的库一起使用时出错

c++ - 高效的 SSE NxN 矩阵乘法

c++ - GNU Readline 库而非 GPL 的简单替代方案

将捕获作为函数指针的 C++ lambda

c++ - C++ 编程中的 vector 类

java - Android:从 C++ 调用带有 byte[] 参数的 java 方法

android - 如何使用 MediaPlayer 在 ListView 中播放多个视频?

ios - YouTube 嵌入视频无法启动

c - 编写一段 C 代码,使编译器使用 SSE4.1 指令生成汇编代码