未知类型名称 __m256 - 无法识别 AVX 的英特尔内在函数?
Unknown type name __m256 - Intel intrinsics for AVX not recognized?
我正在尝试测试一些 Intel Intrinsics,看看它们是如何工作的。所以,我创建了一个函数来为我做这件事,这是代码:
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!\n");
else
printf("Addition : FAILED!\n");
}
但是我收到了这些错误:
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
我正在使用 eclipse Mars
所以我想知道问题是来自编译器还是硬件还是其他什么?
我该如何解决?
谢谢!
MMX 和 SSE2 是 x86-64 的基准,但 AVX 不是。您确实需要专门启用 AVX,而您没有为 SSE2 启用。
使用 -march=haswell
或您实际拥有的任何 CPU 构建。或者只使用 -mavx
.
请注意 gcc -mavx
默认 tune=generic
会将 256b loadu/storeu 内在函数拆分为 vmovups xmm
/ vinsertf128
,如果您的数据实际上是大多数时候对齐,尤其是在 Haswell 上,shuffle-port 吞吐量有限。
不过,如果您的数据确实未对齐,这对 Sandybridge 和 Bulldozer 系列非常有用。参见 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568:它甚至影响 AVX2 向量整数代码,即使所有 AVX2
CPUs(可能除了 Excavator 和 Ryzen)受到这种调整的伤害。 tune=generic
没有考虑启用了哪些指令集扩展,也没有 tune=generic-avx2
。
您可以使用 -mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store
。这仍然没有启用所有现代 x86 CPUs 具有的其他调整选项(例如优化比较和分支的宏融合)(低功耗选项除外),但 gcc 的 tune= 未启用通用的。 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78855).
还有:
I'm including these libraries mmintrin.h, emmintrin.h, xmmintrin.h
不要那样做。 Always just include immintrin.h
in SIMD code。它引入了所有 Intel SSE/AVX 扩展。这就是为什么你得到 error: unknown type name ‘__m256’
请记住,下标向量类型 __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
一起使用。
试试这个
res=_MM_ADD_PS(vec1,vec2);
因为__M256_MM_ADD_PS的原型是
__m256 _MM_ADD_PS(__m256,__m256);
它以两个__m256数据类型作为参数,returns它们的和作为__m256数据,就像
int 添加(int , int);
用于初始化
vec=_MM_setr_PS(7.0,7.0,7.0,7.0,7.0,7.0,7.0,7.0) 或
vec =_MM_LOAD_PS(&arr) 或
vec =_MM_LOAD_PS(ptr)
我正在尝试测试一些 Intel Intrinsics,看看它们是如何工作的。所以,我创建了一个函数来为我做这件事,这是代码:
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!\n");
else
printf("Addition : FAILED!\n");
}
但是我收到了这些错误:
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 我正在使用 eclipse Mars
所以我想知道问题是来自编译器还是硬件还是其他什么? 我该如何解决? 谢谢!
MMX 和 SSE2 是 x86-64 的基准,但 AVX 不是。您确实需要专门启用 AVX,而您没有为 SSE2 启用。
使用 -march=haswell
或您实际拥有的任何 CPU 构建。或者只使用 -mavx
.
请注意 gcc -mavx
默认 tune=generic
会将 256b loadu/storeu 内在函数拆分为 vmovups xmm
/ vinsertf128
,如果您的数据实际上是大多数时候对齐,尤其是在 Haswell 上,shuffle-port 吞吐量有限。
不过,如果您的数据确实未对齐,这对 Sandybridge 和 Bulldozer 系列非常有用。参见 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568:它甚至影响 AVX2 向量整数代码,即使所有 AVX2
CPUs(可能除了 Excavator 和 Ryzen)受到这种调整的伤害。 tune=generic
没有考虑启用了哪些指令集扩展,也没有 tune=generic-avx2
。
您可以使用 -mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store
。这仍然没有启用所有现代 x86 CPUs 具有的其他调整选项(例如优化比较和分支的宏融合)(低功耗选项除外),但 gcc 的 tune= 未启用通用的。 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78855).
还有:
I'm including these libraries mmintrin.h, emmintrin.h, xmmintrin.h
不要那样做。 Always just include immintrin.h
in SIMD code。它引入了所有 Intel SSE/AVX 扩展。这就是为什么你得到 error: unknown type name ‘__m256’
请记住,下标向量类型 __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
一起使用。
试试这个
res=_MM_ADD_PS(vec1,vec2); 因为__M256_MM_ADD_PS的原型是
__m256 _MM_ADD_PS(__m256,__m256);
它以两个__m256数据类型作为参数,returns它们的和作为__m256数据,就像
int 添加(int , int);
用于初始化
vec=_MM_setr_PS(7.0,7.0,7.0,7.0,7.0,7.0,7.0,7.0) 或
vec =_MM_LOAD_PS(&arr) 或
vec =_MM_LOAD_PS(ptr)