大家好我正在尝试使用像这样的英特尔内在函数
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
请有人解释这个
有什么问题答案 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
积分促销应该应用于可变函数的参数......但是如果这里的下标结果不是整数类型之一,则该规则不再适用。