英特尔内部程序包会引起误解



刚开始学习intrinsic,然后发现了一些暴露我无知的东西。这是我所看到的人工版本(VS2015):

__m128i test;
//test.m128i_u16[0] = 127;
//test.m128i_u16[1] = 128;
//test.m128i_u16[2] = 129;
//test.m128i_u16[3] = 130;
//test.m128i_u16[4] = 131;
//test.m128i_u16[5] = 132;
//test.m128i_u16[6] = 133;
//test.m128i_u16[7] = 134;
test.m128i_u16[0] = 50;
test.m128i_u16[1] = 70;
test.m128i_u16[2] = 90;
test.m128i_u16[3] = 110;
test.m128i_u16[4] = 50;
test.m128i_u16[5] = 70;
test.m128i_u16[6] = 90;
test.m128i_u16[7] = 110;
__m128i result = _mm_packus_epi16 (test, test);

所以最后一个命令"使用无符号饱和将打包的16位整数从a和b转换为打包的8位整数,并将结果存储在dst中"。如果我像所示的那样运行,我得到了我所期望的:

-       m128i_i8    char[16]
        [0] 50      char
        [1] 70      char
        [2] 90      chara
        [3] 110     char
        [4] 50      char
        [5] 70      char
        [6] 90      char
        [7] 110     char
        [8] 50      char
        [9] 70      char
        [10] 90     char
        [11] 110    char
        [12] 50     char
        [13] 70     char
        [14] 90     char
        [15] 110    char

但是如果我交换上面的输入(使用注释的值集),那么我得到看起来是整数饱和的结果:-

    m128i_i8        char[16]
        [0]     127     char
        [1]     -128    char
        [2]     -127    char
        [3]     -126    char
        [4]     -125    char
        [5]     -124    char
        [6]     -123    char
        [7]     -122    char
        [8]     127     char
        [9]     -128    char
        [10]    -127    char
        [11]    -126    char
        [12]    -125    char
        [13]    -124    char
        [14]    -123    char
        [15]    -122    char

我在这里错过了什么?解释,命令错了?

您似乎将结果向量打印为持有int8_t,而不是uint8_t元素,即使您做了无符号饱和。因此,大于127的每个值都被打印为负数。

所以饱和到0xFF的所有内容将打印为-1。(饱和到0的所有内容都将打印为0,但int16_t输入都不是负的)。

还请注意,PACKUSWB将其输入视为有符号的,以防不清楚。

最新更新