почему _mm_extract_epi16 не получает ожидаемый результат? - PullRequest
0 голосов
/ 06 июня 2019

Я обнаружил ошибку в моей программе, вызванную неправильно используемой инструкцией SSE '_mm_extract_epi16', как показано ниже:

#include <smmintrin.h>
#include <iostream>

int main(int argc, const char * argv[]) {
    int16_t test_input[8] = {-1, 2, -3, -4, -5, -6, -7, -8};
    __m128i v_input = _mm_load_si128((__m128i *)test_input);
    int32_t extract = (int32_t)(_mm_extract_epi16(v_input, 1));

   return 0;
}

Если извлеченное значение является положительным, то я получаю правильное значение 2. И наоборотполучить неправильное значение «65533».Или я могу использовать приведенный ниже код, чтобы получить правильное значение.

#include <smmintrin.h>
#include <iostream>

int main(int argc, const char * argv[]) {
    int16_t test_input[8] = {-1, 2, -3, -4, -5, -6, -7, -8};
    __m128i v_input = _mm_load_si128((__m128i *)test_input);
   int16_t extract = (_mm_extract_epi16(v_input, 1));
   int32_t result = extract;

   return 0;
}

Я не знаю, почему это происходит.

1 Ответ

3 голосов
/ 06 июня 2019

int _mm_extract_epi16 ( __m128i a, int imm) соответствует поведению asm инструкции pextrw из с расширением нуля в 32-битный регистр.

Встроенный в Intel API-интерфейс использует int повсеместно, даже если неподписанный тип будет более подходящим.

Если вы хотите сделать 16-битное знаковое -расширение на результат,
использовать (int16_t)_mm_extract_epi16(v,1). Или присвойте его переменной int16_t, чтобы верхние байты результата игнорировались для начала.

без знака 65533 = 2 дополнения -3. Это нормально. (2 16 - 3 = 65533 = 0xfffd)

...