c/c++开发分享仅使用SSE2提取SSE混洗32位值

我试图以有效的方式从128位寄存器中提取4个字节。 问题是每个值都是32 {120,0,0,0,55,0,0,0,42,0,0,0,120,0,0,0} 。 我想将128位变换为32位,forms为{120,55,42,120}

“原始”代码如下所示:

 __m128i byte_result_vec={120,0,0,0,55,0,0,0,42,0,0,0,120,0,0,0}; unsigned char * byte_result_array=(unsigned char*)&byte_result_vec; result_array[x]=byte_result_array[0]; result_array[x+1]=byte_result_array[4]; result_array[x+2]=byte_result_array[8]; result_array[x+3]=byte_result_array[12]; 

我的SSSE3代码是:

 unsigned int * byte_result_array=...; __m128i byte_result_vec={120,0,0,0,55,0,0,0,42,0,0,0,120,0,0,0}; const __m128i eight_bit_shuffle_mask=_mm_set_epi8(1,1,1,1,1,1,1,1,1,1,1,1,0,4,8,12); byte_result_vec=_mm_shuffle_epi8(byte_result_vec,eight_bit_shuffle_mask); unsigned int * byte_result_array=(unsigned int*)&byte_result_vec; result_array[x]=byte_result_array[0]; 

我怎样才能有效地使用SSE2。 SSSE3或SSE4有更好的版本吗?

    您可以查看我之前的答案,了解一些解决方案和相反的操作。

    特别是在SSE2中,您可以通过首先将32位整数打包为带符号的16位整数并使其饱和来实现:

     byte_result_vec = _mm_packs_epi32(byte_result_vec, byte_result_vec); 

    然后我们使用无符号饱和将这些16位值打包成无符号8位值:

     byte_result_vec = _mm_packus_epi16(byte_result_vec, byte_result_vec); 

    然后我们最终可以从寄存器的低32位取值:

     int int_result = _mm_cvtsi128_si32(byte_result_vec); unsigned char* byte_result_array = (unsigned char*)&int_result; result_array[x] = byte_result_array[0]; result_array[x+1] = byte_result_array[1]; result_array[x+2] = byte_result_array[2]; result_array[x+3] = byte_result_array[3]; 

    编辑:以上假设8位字最初位于各自32位字的低字节中,其余字用0 s填充,否则它们将在饱和打包过程中被钳位。 因此,操作如下:

      byte 15 0 0 0 0 D 0 0 0 C 0 0 0 B 0 0 0 A _mm_packs_epi32 -> 0 D 0 C 0 B 0 A 0 D 0 C 0 B 0 A _mm_packus_epi16 -> DCBADCBADCBADCBA ^^^^^^^ _mm_cvtsi128_si32 -> int DCBA, laid out in x86 memory as bytes ABCD -> reinterpreted as unsigned char array { A, B, C, D } 

    如果不间断的字节最初没有用0填充,则必须事先将它们掩盖掉:

     byte_result_vec = _mm_and_si128(byte_result_vec, _mm_set1_epi32(0x000000FF)); 

    或者,如果有趣的字节最初是高字节,则必须事先将它们转换为低字节:

     byte_result_vec = _mm_srli_epi32(byte_result_vec, 24); 

    或者,如果你真的想要{ D, C, B, A } (我的问题对我来说并不完全清楚),那么这相当于只是在分配中切换数组索引(或者交替执行32位)事先在初始SSE寄存器上shuffle( _mm_shuffle_epi32 )。

      以上就是c/c++开发分享仅使用SSE2提取SSE混洗32位值相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(猴子技术宅)。

      本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/545810.html

      发表评论

      电子邮件地址不会被公开。 必填项已用*标注