英特尔内部函数的问题
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
大家好,我正在尝试像这样使用英特尔内部函数
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
.
您应该可以通过显式转换来解决此问题,例如:
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