[英]gcc target for AVX2 disabling SSE instruction set
我们有一个我们想用AVX2编译的翻译单元(只有那个):它正在告诉GCC,在文件的第一行:
#pragma GCC target "arch=core-avx2,tune=core-avx2"
这曾经与GCC 4.8和4.9一起使用,但从6开始(尝试7和8)我们得到这个警告(我们视为错误):
error: SSE instruction set disabled, using 387 arithmetics
在返回浮点数的第一个函数上。 我试图像这样启用SSE 4.2(以及avx和avx2)
#pragma GCC target "sse4.2,arch=core-avx2,tune=core-avx2"
但这还不够,错误仍然存在。
编辑:
相关的编译器标志,我们针对大多数东西定位AVX:
-mfpmath=sse,387 -march=corei7-avx -mtune=corei7-avx
EDIT2:最小样本:
#pragma GCC target "arch=core-avx2,tune=core-avx2"
#include <immintrin.h>
#include <math.h>
static inline float
lg1pf( float x ) {
return log1pf(x)*1.44269504088896338700465f;
}
int main()
{
log1pf(2.0f);
}
编译方式:
gcc -o test test.c -O2 -Wall -Werror -pedantic -std=c99 -mfpmath=sse,387 -march=corei7-avx -mtune=corei7-avx
In file included from /home/xxx/gcc-7.1.0/lib/gcc/x86_64-pc-linux-gnu/7.1.0/include/immintrin.h:45:0,
from test.c:3:
/home/xxx/gcc-7.1.0/lib/gcc/x86_64-pc-linux-gnu/7.1.0/include/avx512fintrin.h: In function ‘_mm_add_round_sd’:
/home/xxx/gcc-7.1.0/lib/gcc/x86_64-pc-linux-gnu/7.1.0/include/avx512fintrin.h:1412:1: error: SSE register return with SSE disabled
{
^
GCC详细信息(我没有用于编译它的标志)gcc --version gcc(GCC)7.1.0版权所有(C)2017 Free Software Foundation,Inc。这是免费软件; 查看复制条件的来源。 没有保修; 甚至不适用于适销性或特定用途的适用性。
潜在解决方案
#pragma GCC target "avx2"
在没有对代码进行其他更改的情况下为我工作。 将属性应用于单个函数也不起作用:
相关问题:
__attribute__((__target__("arch=broadwell"))) // does not compile
__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }
__attribute__((__target__("avx2,arch=broadwell"))) // does not compile
__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }
__attribute__((__target__("avx2"))) // compiles
__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }
这看起来像一个bug。 #pragma GCC target
#include <immintrin.h>
之前的#pragma GCC target
以某种方式打破了标题,IDK为什么。 即使在-march=haswell
的命令行上启用了AVX2,#pragma似乎-march=haswell
破坏之后定义的任何内在函数的内联。
您可以在标头之后使用#pragma
,但是然后使用未在命令行上启用的instrinsics会失败。
即使像#pragma GCC target "arch=haswell"
这样的更现代的目标名称#pragma GCC target "arch=haswell"
导致错误,所以并不是像corei7-avx
这样古老的模糊目标名称一般都会被破坏。 他们仍然在命令行上工作。 如果要为整个文件启用某些内容,标准方法是使用编译器选项而不是编译指示。
尽管如此,GCC确实声称支持基于pragma或__attribute__
的每个功能的目标选项。 https://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html 。
这就是我已经开始玩这个了( 带有gcc8.1的Godbolt编译器浏览器 )。 Clang不受影响,因为它忽略了#pragma GCC target
。 (这意味着#pragma
不是非常便携;你可能希望你的代码适用于任何GNU C编译器,而不仅仅是gcc本身。)
// breaks gcc when before immintrin.h
// #pragma GCC target "arch=haswell"
#include <immintrin.h>
#include <math.h>
//#pragma GCC target "arch=core-avx2,tune=core-avx2"
#pragma GCC target "arch=haswell"
//static inline
float
lg1pf( float x ) {
return log1pf(x)*1.44269504088896338700465f;
}
// can accept / return wide vectors
__m128 nop(__m128 a) { return a; }
__m256 require_avx(__m256 a) { return a; }
// but error on using intrinsics if #include happened without target options
//__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }
// this works, though, because AVX is enabled at this point
// presumably so would __builtin_ia32_whatever
// Without `arch=haswell`, this breaks, so we know the pragma "worked"
__m256 use_native_vec(__m256 a) { return a+a; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.