使用 AVX/AVX2/SSE __m128i 将所有负字节设置为 -128 (0x80) 并保留所有其他字节

Noa*_*oah 2 sse simd avx avx2

基本上我想要做的是获取一个__m128i寄存器,并为每个负字节将其值设置为 -128 (0x80) 并且不更改任何正值。

确切地说是:

signed char __m128_as_char_arr[16] = {some data};
for(int i = 0; i < 16; i++) {
     if (__m128_as_char_arr[i] < 0) { //alternative __m128_as_char_arr[i] & 0x80
           __m128_as_char_arr[i] = 0x80;
     }

}
Run Code Online (Sandbox Code Playgroud)

我认为最好的方法是:

__m128i v = some data;
int mask = _mm_movemask_epi8(_mm_cmpgt_epi8(_mm_set1_epi8(0xff), v));

// use mask in some way to only set chars with 1s bit set
Run Code Online (Sandbox Code Playgroud)

但我不知道 (1) 使用什么指令来仅设置与关联的字节mask以及 (2) 是否有更好的方法来做到这一点(根本没有掩码或生成掩码的更好方法)。

Pau*_*l R 7

您可以将这些值视为未签名并使用最小操作(_mm_min_epu8 ),例如

v = _mm_min_epu8(v, _mm_set1_epi8(128));
Run Code Online (Sandbox Code Playgroud)

除了作为廉价指令外,这还适用于 SSE2 及更高版本。