__m256类型的intel intrinsics问题

时间:2016-07-29 15:19:58

标签: c++ c intel intrinsics avx

我正在尝试测试一些英特尔内在函数,看看它们是如何工作的。所以,我为我创建了一个函数,这就是代码:

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

所以我想知道的是问题是来自编译器还是硬件或其他东西? 我该如何解决? 谢谢!

2 个答案:

答案 0 :(得分:6)

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

使用-march=haswell或您实际拥有的任何CPU进行构建。或者只使用-mavx

请注意,使用默认gcc -mavx的{​​{1}}会将256b loadu / storeu内在函数拆分为tune=generic / vmovups xmm,如果您的数据实际上与时间,特别是Haswell的洗牌端口吞吐量有限。

如果您的数据确实不对齐,那么它对Sandybridge和Bulldozer家族有好处。请参阅https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568:它甚至会影响AVX2矢量整数代码,即使所有AVX2也是如此 这种调整会损害CPU(挖掘机和Ryzen除外)。 vinsertf128没有考虑启用了哪个指令集扩展,并且没有tune=generic

您可以使用tune=generic-avx2。这仍然没有启用所有现代x86 CPU所具有的其他调整选项(如优化比较和分支的宏融合)(除了低功率的),但gcc' s 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扩展。这就是你得到-mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store

的原因

请记住,下标矢量类型谎言error: unknown type name ‘__m256’是非标准且不可移植的。它们不是数组,并且 从寄存器中的SIMD向量中提取第3个元素或其他内容需要随机指令,而不是负载。

如果你想为矢量类型提供方便的包装器,让你可以使用__m256来从矢量变量的元素中提取标量,那么看看Agner Fog' s Vector Class Library。它是GPL,所以如果这是一个问题,你必须查看其他包装库。

它可以让你做像

这样的事情
[]

您可以在VCL类型上使用常规内在函数。 operator[]// example from the manual for operator[] Vec4i a(10,11,12,13); int b = a[2]; // b = 12 上的透明包装,因此您可以将其与Vec8f一起使用。

答案 1 :(得分:1)

试试这个

解析度= _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)