未知类型名称__M256-英特尔AVX内部功能无法识别?
我正在尝试测试一些Intel Intrinsic,看看它们是如何工作的。因此,我创建了一个函数来执行此操作,代码如下:
void test_intel_256()
{
__m256 res,vec1,vec2;
__M256_MM_SET_PS(vec1, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0);
__M256_MM_SET_PS(vec1, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0);
__M256_MM_ADD_PS(res,vec1,vec2);
if (res[0] ==9 && res[1] ==9 && res[2] ==9 && res[3] ==9
&& res[4] ==9 && res[5] ==9 && res[6] ==9 && res[7] ==9 )
printf("Addition : OK!
");
else
printf("Addition : FAILED!
");
}
但我收到以下错误:
error: unknown type name ‘__m256’
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
error: subscripted value is neither array nor pointer nor vector
意味着编译器无法识别__m256类型,因此他不能将res视为浮点数组。 我正在包括这些库mmintrin.h、emmintrin.h、xmmintrin.h 我正在使用月食火星
所以我想知道的是,问题出在编译器、硬件还是其他方面? 我怎么才能解决这个问题呢? 谢谢!
解决方案
mmx和sse2是x86-64的基准,但avx不是。您确实需要专门启用AVX,而您没有启用SSE2。
使用-march=haswell
或您实际拥有的任何CPU进行构建。或仅使用-mavx
。
请注意,默认设置为tune=generic
的gcc -mavx
会将256b的装入/存储内部划分为vmovups xmm
/vinsertf128
,如果您的数据在大部分时间内实际上是对齐的,这是不好的,尤其是在洗牌端口吞吐量有限的Haswell上。
不过,如果您的数据确实不一致,这对Sandybridge和Bulldozer家族是有好处的。参见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568:它甚至会影响AVX2向量整数代码,即使所有AVX2
CPU(可能除了挖掘机和瑞森)会受到这种调优的影响。tune=generic
不考虑启用了哪些指令集扩展,并且没有tune=generic-avx2
。
您可以使用-mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store
。这仍然不支持所有现代x86 CPU都具有的其他调优选项(如针对比较和分支的宏观融合进行优化)(低功耗CPU除外),但这不是通过GCC的Tune=Generic实现的。(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78855)。
同时:
我将包括这些库mmintrin.h、emmintrin.h、xmmintrin.h
不要那样做。Always just include immintrin.h
in SIMD code。它吸引了所有英特尔SSE/AVX扩展。这就是您获得error: unknown type name ‘__m256’
请记住,下标向量类型是非标准的和不可移植的。它们不是数组,应该期望
[]
像数组一样工作。从寄存器中的SIMD向量提取第三个元素或其他元素需要无序指令,而不是加载。
如果您想要方便的向量类型包装器,使您可以使用
operator[]
从向量变量的元素中提取标量,请看一下Agner Fog的Vector Class Library。它是GPLed的,所以如果有问题,您必须查看其他包装库。
它允许您执行以下操作
// example from the manual for operator[]
Vec4i a(10,11,12,13);
int b = a[2]; // b = 12
您可以对VCL类型使用普通内部函数。Vec8f
是__m256
上的透明包装,因此您可以将其与_mm256_mul_ps
一起使用。
相关文章