intel内在函数的问题

时间:2016-07-28 15:18:41

标签: c 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

请有人解释这个

有什么问题

2 个答案:

答案 0 :(得分:5)

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

在退出该功能之前,不要忘记调用_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

答案 1 :(得分:3)

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

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

看起来编译器没有将通常的整数提升应用于下标的__m64变量,因此您传递的每个值都消耗16位参数空间(可能在堆栈上),然后{{1为每个printf解码32位。

您应该可以使用显式强制转换修复此问题,例如:

%u

积分促销应该应用于可变函数的参数......但是如果这里的下标结果不是整数类型之一,则该规则不再适用。