SSE2:如何将 _m128 简化为一个单词

Posted

技术标签:

【中文标题】SSE2:如何将 _m128 简化为一个单词【英文标题】:SSE2: How to reduce a _m128 to a word 【发布时间】:2009-11-13 11:29:54 【问题描述】:

将 a _m128(4 个单词 a b c d)减少到一个单词的最佳方法是什么( sse2 )? 我想要每个 _m128 组件的低部分:

int result = ( _m128.a & 0x000000ff ) <<  24
        | ( _m128.b & 0x000000ff ) << 16
        | ( _m128.c & 0x000000ff ) << 8
        | ( _m128.d & 0x000000ff ) << 0

有没有内在函数?谢谢!

【问题讨论】:

【参考方案1】:

仅供参考,sse3 内在函数 _mm_shuffle_epi8 完成这项工作:(在这种情况下使用掩码 0x0004080c)

【讨论】:

_mm_shuffle_epi8 (PSHUFB) 是 SSSE3(又名 SSE3.5 又名 MNI)。否则很好的答案:+1。【参考方案2】:

SSE2 答案需要多个指令:

unsigned benoit(__m128i x)

    __m128i zero = _mm_setzero_si128(), mask = _mm_set1_epi32(255);
    return _mm_cvtsi128_si32(
                _mm_packus_epi16(
                        _mm_packus_epi16(
                                _mm_and_si128(x, mask), zero), zero));

在 %xmm1 中输入,在 %rax 中输出的情况下,以上相当于 5 个机器操作:

 pxor     %xmm0, %xmm0
 pand     MASK, %xmm1
 packuswb %xmm0, %xmm1
 packuswb %xmm0, %xmm1
 movd     %xmm1, %rax

如果您想了解 SSE2 的一些不寻常用途,包括高速位矩阵转置、字符串搜索和双调(GPGPU 样式)排序,您可能需要查看我的博客 Coding on the edges

无论如何,希望对您有所帮助。

【讨论】:

以上是关于SSE2:如何将 _m128 简化为一个单词的主要内容,如果未能解决你的问题,请参考以下文章

是否启用了 SSE2 指令?

C 内在函数、SSE2 点积和 gcc -O3 生成的程序集

如何将 16 字节的内存加载到 Rust __m128i 中?

移动 __m128 的上下浮动

SSE2 双倍乘法比标准乘法慢

将 SSE2 迁移到 Arm NEON 内部函数