当我使用_mm_packus_epi16时,小于零的值将变为零,但高于127的数字将变为负值。
根据此链接,它应该是无符号饱和度 http://msdn.microsoft.com/en-us/library/07ad1wx4%28v=vs.90%29.aspx
但没有发生
有什么建议吗?
代码:
__m128i result, resultHi, resultLo;
//processing.....
result = _mm_packus_epi16(resultLo, resultHi);
答案 0 :(得分:5)
我怀疑你只是误解了输出数据,例如将其显示为带符号的8位而不是无符号。无论如何,这是一个演示程序,可能有助于澄清事情:
#include <xmmintrin.h>
#include <stdio.h>
int main(void)
{
__m128i resultLo = _mm_setr_epi16(800, 700, 600, 500, 400, 300, 200, 100);
__m128i resultHi = _mm_setr_epi16(0, -100, -200, -300, -400, -500, -600, -700);
__m128i result = _mm_packus_epi16(resultLo, resultHi);
printf("resultLo = %vhd\n", resultLo);
printf("resultHi = %vhd\n", resultHi);
printf("result = %vu\n", result);
return 0;
}
编译并运行:
$ gcc -Wall -msse3 packus.c && ./a.out
resultLo = 800 700 600 500 400 300 200 100
resultHi = 0 -100 -200 -300 -400 -500 -600 -700
result = 255 255 255 255 255 255 200 100 0 0 0 0 0 0 0 0
$
答案 1 :(得分:2)
由于UnsignedSaturate
将16位有符号整数转换为8位无符号整数,因此需要一种方法来处理不适合的值,因此值小于0(请记住,您来自有符号值被剪切为0而大于255的值被剪切为255。
如果您将结果值130转换为无符号8位字符,那么如果您将该数据解释为带符号的8位字符,则该值为-126。
由于您使用__m128i
来保存结果,您必须自己进行转换(即从签名到无符号),除非您对SSE使用某些特定扩展(例如Microsoft的m128i_u8
)
总之:你只是解释数据错误。