X86 将8个16位SSE寄存器转换为8位数据

X86 将8个16位SSE寄存器转换为8位数据,x86,intel,sse,simd,X86,Intel,Sse,Simd,假设我有一个16位数据的SSE阵列: {1,2,3,4,5,6,7,8} 现在,我需要通过在前8个字节中仅存储16位数据的低位字节,将此SSE数组转换为8位数据,如: {1,2,3,4,5,6,7,8,0,0,0,0,0,0,0}. 是否有任何SSE指令来执行此操作?如上面的注释所述,您可以很容易地使用,例如 #包括 #包括 静态m128i组件16至8(常数m128i v) { 常数m128i vperm=_mm_setr_epi8(0,2,4,6,8,10,12,14,-1,-1,-1,-1,

假设我有一个16位数据的SSE阵列:

{1,2,3,4,5,6,7,8}

现在,我需要通过在前8个字节中仅存储16位数据的低位字节,将此SSE数组转换为8位数据,如:

{1,2,3,4,5,6,7,8,0,0,0,0,0,0,0}.

是否有任何SSE指令来执行此操作?

如上面的注释所述,您可以很容易地使用,例如

#包括
#包括
静态m128i组件16至8(常数m128i v)
{
常数m128i vperm=_mm_setr_epi8(0,2,4,6,8,10,12,14,-1,-1,-1,-1,-1,-1);
return-mm-shuffle-epi8(v,vperm);
}
内部主(空)
{
常数m128i v=_mm_setr_epi16(1,2,3,4,5,6,7,8);
printf(“%vhd->%vd\n”,v,第16至8(v)包);
返回0;
}
编译并运行:

$ gcc -Wall -mssse3 pack_16_to_8.c && ./a.out

1 2 3 4 5 6 7 8 -> 1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0

补充Paul K的答案:

SSE2扩展包含命令和。这些命令专门设计用于将16位向量转换为8位向量。如果16位(有符号和无符号)值超过范围8位无符号整数(0..255),则它们将执行饱和


pshufb
可以做到这一点,实际的pack指令是饱和的,请参见在数组上执行此操作,而不是打包单个向量并在高64b中保留零。
#include <iostream>
#include <emmintrin.h>

template<class T> inline void Print(const __m128i & v)
{
    T b[sizeof(v) / sizeof(T)];
    _mm_storeu_si128((__m128i*)b, v);
    for (int i = 0; i < sizeof(v) / sizeof(T); i++)
        std::cout << int(b[i]) << " ";
    std::cout << std::endl;
}

int main()
{
    __m128i v16 = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);

    Print<uint8_t>(_mm_packs_epi16(v16, _mm_setzero_si128()));
    Print<uint8_t>(_mm_packus_epi16(v16, _mm_setzero_si128()));

    return 0;
}
1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0
1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0