4

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

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

有没有内在函数?谢谢 !

4

2 回答 2

2

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

于 2009-11-18T17:27:52.253 回答
1

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

无论如何,希望这会有所帮助。

于 2012-04-20T05:17:41.520 回答