#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 обрабатывает свои входные данные как подписанные, если это было неясно.