Недопонимание команд встроенного пакета Intel

#x86 #intel #sse #intrinsics

#x86 #intel #sse #встроенные

Вопрос:

Просто начинаю с intrinsics и натыкаюсь на что-то, что разоблачило мое невежество. Вот искусственная версия того, что я вижу (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
  

Чего мне здесь не хватает? Интерпретация, неправильная команда?

Комментарии:

1. Ваш вопрос был бы НАМНОГО короче и проще для чтения, если бы вы создали таблицу, в которой соответствующие входы и выходы выстроились (по горизонтали или вертикали).

Ответ №1:

Похоже, что вы печатаете свой результирующий вектор как удерживающий int8_t , а не uint8_t как элементы, даже если вы выполнили насыщение без знака. Таким образом, каждое значение выше 127 печатается как отрицательное число.

Таким образом, все, что насыщено до 0xFF, будет напечатано как -1. (Все, что насыщено до 0, будет напечатано как 0, но ни один из ваших входных данных int16_t не был отрицательным).

Также обратите внимание, что PACKUSWB обрабатывает свои входные данные как подписанные, если это было неясно.