_mm_packus_epi16饱和度问题

时间:2014-07-15 12:24:25

标签: c++ c x86 sse simd

当我使用_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);

2 个答案:

答案 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

总之:你只是解释数据错误