为什么_mm_extract_epi16没有得到预期的结果?

时间:2019-06-06 01:56:47

标签: c sse intrinsics sign-extension

我发现我的程序中的错误是由滥用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 个答案:

答案 0 :(得分:3)

int _mm_extract_epi16 ( __m128i a, int imm)将{em>零扩展的pextrw instruction的asm行为匹配到一个32位寄存器中。

即使无符号类型更合适,英特尔的内在API仍在各处使用int

如果要对结果进行16位 sign 扩展,
使用(int16_t)_mm_extract_epi16(v,1) 。或将其分配给int16_t变量,以便从头开始忽略结果的高字节。

无符号65533 = 2的补码-3。这是正常的。 (2 16 -3 = 65533 = 0xfffd