__m256类型的intel内在函数问题

A.n*_*chi 5 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");
}
Run Code Online (Sandbox Code Playgroud)

但后来我收到了这些错误:

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
Run Code Online (Sandbox Code Playgroud)

这意味着编译器无法识别__m256类型,因此他无法将res视为浮点数组.我包括这些库mmintrin.h,emmintrin.h,xmmintrin.h 并且我正在使用eclipse Mars

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

Pet*_*des 7

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 CPU(挖掘机和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).


也:

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

不要那样做. 始终只包含immintrin.hSIMD代码.它引入了所有英特尔SSE/AVX扩展.这就是你得到的原因error: unknown type name ‘__m256’


请记住,下标矢量类型__m256是非标准和不可移植的.他们不是数组,而且也没有理由你应该期待[]像一个阵列工作.从寄存器中的SIMD向量中提取第3个元素或其他内容需要shuffle指令,而不是加载.


如果你想为矢量类型提供方便的包装器,让你可以operator[]用来从矢量变量的元素中提取标量,那么看看Agner Fog的Vector类库.它是GPLed,所以如果这是一个问题,你将不得不查看其他包装库.

它可以让你做的事情

// example from the manual for operator[]
Vec4i a(10,11,12,13);
int b = a[2];   // b = 12
Run Code Online (Sandbox Code Playgroud)

您可以在VCL类型上使用常规内在函数. Vec8f是一个透明的包装器__m256,所以你可以使用它_mm256_mul_ps.