使用 SSE 内在函数,我得到了一个包含四个 32 位浮点数的向量,这些浮点数被限制在 0-255 的范围内并四舍五入到最接近的整数。我现在想把这四个写成字节。
有一个内在函数_mm_cvtps_pi8
可以将 32 位转换为 8 位有符号整数,但问题是任何超过 127 的值都会被限制为 127。我找不到任何可以限制为无符号 8 位值的指令。
我有一种直觉,我可能想要做的是某种组合,_mm_cvtps_pi16
然后_mm_shuffle_pi8
是移动指令,以将我关心的四个字节放入内存。这是最好的方法吗?我要看看我是否能弄清楚如何对随机播放控制掩码进行编码。
更新:以下似乎完全符合我的要求。有没有更好的办法?
#include <tmmintrin.h>
#include <stdio.h>
unsigned char out[8];
unsigned char shuf[8] = { 0, 2, 4, 6, 128, 128, 128, 128 };
float ins[4] = {500, 0, 120, 240};
int main()
{
__m128 x = _mm_load_ps(ins); // Load the floats
__m64 y = _mm_cvtps_pi16(x); // Convert them to 16-bit ints
__m64 sh = *(__m64*)shuf; // Get the shuffle mask into a register
y = _mm_shuffle_pi8(y, sh); // Shuffle the lower byte of each into the first four bytes
*(int*)out = _mm_cvtsi64_si32(y); // Store the lower 32 bits
printf("%d\n", out[0]);
printf("%d\n", out[1]);
printf("%d\n", out[2]);
printf("%d\n", out[3]);
return 0;
}
UPDATE2:这是基于 Harold 回答的更好的解决方案:
#include <smmintrin.h>
#include <stdio.h>
unsigned char out[8];
float ins[4] = {10.4, 10.6, 120, 100000};
int main()
{
__m128 x = _mm_load_ps(ins); // Load the floats
__m128i y = _mm_cvtps_epi32(x); // Convert them to 32-bit ints
y = _mm_packus_epi32(y, y); // Pack down to 16 bits
y = _mm_packus_epi16(y, y); // Pack down to 8 bits
*(int*)out = _mm_cvtsi128_si32(y); // Store the lower 32 bits
printf("%d\n", out[0]);
printf("%d\n", out[1]);
printf("%d\n", out[2]);
printf("%d\n", out[3]);
return 0;
}