首页 > 解决方案 > 为什么 _mm_extract_epi16 没有得到预期的结果?

问题描述

我在我的程序中发现了由滥用 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;
}

我不知道为什么会这样。

标签: csseintrinsicssign-extension

解决方案


int _mm_extract_epi16 ( __m128i a, int imm)匹配零扩展到 32 位寄存器的pextrw指令的asm 行为。

int即使在无符号类型更合适的情况下,英特尔的内在 API 也到处使用。

如果要对结果进行 16 位符号扩展,请
使用(int16_t)_mm_extract_epi16(v,1). 或者将它分配给一个int16_t变量,这样结果的高字节就被忽略了。

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


推荐阅读