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

问题描述 投票:0回答:2

我正在尝试测试一些英特尔内部函数,看看它们是如何工作的。因此,我创建了一个函数来为我执行此操作,这就是代码:

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.hemmintrin.hxmmintrin.h 我正在使用 eclipse Mars

所以我想知道问题是出在编译器还是硬件还是其他什么地方? 我该如何解决它? 谢谢!

c++ c intel intrinsics avx
2个回答
14
投票

MMX 和 SSE2 是 x86-64 的基准,但 AVX 不是。 您需要专门启用 AVX,而 SSE2 则不需要。

使用

-march=haswell

 或您实际拥有的任何 CPU 进行构建。  或者直接使用 
-mavx

请注意,

gcc -mavx

(GCC10 左右之前)使用默认的 
tune=generic
 会将 256b loadu/storeu 内在函数
拆分为 vmovups xmm /
vinsertf128
,如果您的数据实际上大多数时间都是对齐的,那么这很糟糕,尤其是 Haswell 上的情况尤其糟糕,因为 shuffle 端口吞吐量有限。
不过,如果您的数据确实未对齐,这对 Sandybridge 和 Bulldozer 系列来说是有好处的。  请参阅 

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568

:它甚至会影响 AVX2 向量整数代码,即使所有 AVX2 CPU(Excavator 和 Ryzen 除外)会受到这种调整的损害。 tune=generic 不考虑启用了哪些指令集扩展,并且没有

tune=generic-avx2
您可以使用

-mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store

。 这仍然无法启用所有现代 x86 CPU(低功耗 CPU 除外)都具有的其他调整选项(例如针对比较和分支的宏融合进行优化),但 gcc 的une=generic 无法启用该选项。 (

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78855
)。

还有:

我包括这些库 mmintrin.h、emmintrin.h、xmmintrin.h

不要这样做。
始终只在 SIMD 代码中包含

immintrin.h。 它引入了所有 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
 一起使用。

试试这个

1
投票
res=_MM_ADD_PS(vec1,vec2); 因为__M256_MM_ADD_PS的原型是

__m256 _MM_ADD_PS(__m256,__m256);

它接受两个 __m256 数据类型作为参数,并将它们的总和作为 __m256 数据返回,就像

int add(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)

© www.soinside.com 2019 - 2024. All rights reserved.