c++ - 未知类型名称 __m256 - 无法识别 AVX 的英特尔内在函数?

标签 c++ c intel intrinsics avx

我正在尝试测试一些 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 视为 float 组。 我包括这些库 mmintrin.hemmintrin.hxmmintrin.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 vector 整数代码,即使所有 AVX2 CPU(也许 Excavator 和 Ryzen 除外)会受到此调整的损害。 tune=generic 没有考虑启用的指令集扩展,也没有 tune=generic-avx2

您可以使用 -mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store。这仍然无法启用所有现代 x86 CPU(低功耗处理器除外)都具有的其他调整选项(例如优化比较和分支的宏融合),但 gcc 的 tune=generic 无法启用。 (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 .它引入了所有英特尔 SSE/AVX 扩展。这就是您收到 error: unknown type name ‘__m256’

的原因

请记住,下标 vector 类型 __m256 是非标准且不可移植的。它们不是数组,您没有理由应该期望 [] 像数组一样工作。从寄存器中的 SIMD vector 中提取第三个元素或其他元素需要混洗指令,而不是加载。


如果您想要方便的 vector 类型包装器,让您可以使用 operator[] 从 vector 变量的元素中提取标量,请查看 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 一起使用。

关于c++ - 未知类型名称 __m256 - 无法识别 AVX 的英特尔内在函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38662287/

相关文章:

x86 - 跳转到保护模式不起作用或没有效果

c++ - 从 com 端口 rs232 读取阻塞模式

c++ - 如果指针是一个函数 arguemente 并且正在通过引用传递值,我应该删除它吗?

c - while循环,当它运行 "string"数据时,如何用特定的单词或字母中止它?

c - 循环运行的程序意外终止

c++ - tbb:concurrent_unordered_map() - vector 中每个唯一元素的 ID?

android - 启用英特尔虚拟化技术

c++ - 如何使用cmake在linux下构建Qt项目

C++ 指针算术循环访问冲突

对于 c 中的猜谜游戏,无法获得除 "Too High"之外的结果