英特尔内部函数的问题

Issues with intel intrinsics

大家好,我正在尝试像这样使用英特尔内部函数

void test()
{
    uint16_t n1 = 5;
    uint16_t n2 = 2;
    __m64 vec1, vec2, res;

    vec1 = _mm_set_pi16(n1, n1, n1, n1);
    vec2 = _mm_set_pi16(n2, n2, n2, n2);

    res = _mm_add_pi16(vec1, vec2);

    printf("%u %u %u %u \n", vec1[0], vec1[1], vec1[2], vec1[3]);
    printf("%u %u %u %u \n", vec2[0], vec2[1], vec2[2], vec2[3]);
    printf("%u %u %u %u \n", res[0], res[1], res[2], res[3]);
}   

但我得到的结果很奇怪:

327685 327685 131074 131074 
131074 131074 458759 458759 
458759 458759 327685 327685 

我正在使用 eclipse Mars...我包括 mmintrin.h, xmmintrin.h, emmintrin.h.

谁能解释一下这有什么问题

让我们将这些值转换为十六进制字符串:

0x00050005    0x00050005    0x00020002    0x00020002
0x00020002    0x00020002    0x00070007    0x00070007
0x00070007    0x00070007    0x00050005    0x00050005

编译器似乎没有对带下标的 __m64 变量应用通常的整数提升,因此您传递的每个值都占用参数 space 的 16 位(可能在堆栈上) ,然后 printf 为每个 %u.

解码 32 位

您应该可以通过显式转换来解决此问题,例如:

printf("%u %u %u %u \n", (unsigned int)vec1[0], (unsigned int)vec1[1],
                         (unsigned int)vec1[2], (unsigned int)vec1[3]);

整数提升应该应用于可变函数的参数...但如果此处下标的结果不完全是整数类型之一,则该规则不再适用。

引用 __m64 作为非标准数组。
不知道你的编译器是怎么处理的
我在 Visual Studio 中使用英特尔编译器,遇到编译错误。 在打印之前,您应该从 MMX 寄存器中提取 uint16 个元素到 ALU 寄存器。
使用 _mm_extract_pi16 内在提取值。

不要忘记在退出函数之前调用 _mm_empty() 内部函数。

参见以下代码示例:

#include <stdint.h>
#include <stdio.h>

#include <mmintrin.h>
#include <xmmintrin.h>
#include <emmintrin.h>

static void Test()
{
    uint16_t n1=5;
    uint16_t n2=2;
    __m64 vec1,vec2,res;

    vec1 = _mm_set_pi16 (n1 ,n1 ,n1 ,n1);
    vec2 = _mm_set_pi16 (n2 ,n2 ,n2 ,n2);

    res = _mm_add_pi16 (vec1, vec2);

    //uint16_t res0 = _mm_extract_pi16(res, 0);
    //uint16_t res1 = _mm_extract_pi16(res, 1);
    //uint16_t res2 = _mm_extract_pi16(res, 2);
    //uint16_t res3 = _mm_extract_pi16(res, 3);

    printf("%u %u %u %u \n",_mm_extract_pi16(vec1, 0),_mm_extract_pi16(vec1, 1),_mm_extract_pi16(vec1, 2),_mm_extract_pi16(vec1, 3));
    printf("%u %u %u %u \n",_mm_extract_pi16(vec2, 0),_mm_extract_pi16(vec2, 1),_mm_extract_pi16(vec2, 2),_mm_extract_pi16(vec2, 3));
    printf("%u %u %u %u \n",_mm_extract_pi16(res, 0),_mm_extract_pi16(res, 1),_mm_extract_pi16(res, 2),_mm_extract_pi16(res, 3));

    _mm_empty();
}

int main()
{
    Test();

    return 0;
}

输出:

5 5 5 5
2 2 2 2
7 7 7 7