如果我#include <immintrin.h>
,我会收到此错误:
错误:"__builtin_ia32_addpd256"未在此范围内声明
我已经定义了__AVX__
宏并__FMA__
宏以使AVX可用,但显然这还不够。如果我使用编译器标志-mavx
而不是宏,则没有错误,但该解决方案是不可接受的。那么,我还应该定义什么来使用 AVX?
您不应该定义__AVX__
并自己__FMA__
- 当您启用正确的编译器选项时,这些选项会自动定义,例如
gcc -Wall -mavx ...
如果您有兴趣,可以自己检查一下:
无 AVX:
$ gcc -dM -E - < /dev/null | egrep "AVX|FMA"
$
AVX:
$ gcc -mavx -dM -E - < /dev/null | egrep "AVX|FMA"
#define __AVX__ 1
$
AVX + FMA:
$ gcc -mavx -mfma -dM -E - < /dev/null | egrep "AVX|FMA"
#define __AVX__ 1
#define __FMA__ 1
$
正确的解决方案可能是拥有一个包含处理器特定内部函数的特定文件。并且您仅为此文件设置 -mavx -mfma 选项。程序本身确定在运行时调用哪个版本。
我使用 GCC 助手在运行时获得最佳优化版本。
func_avx_fma.c
void domagic_avx_fma(...) {}
func_general.c
void domagic_general(...) {}
助手.c
void domagic_avx_fma(...);
void domagic_general(...);
typedef void (*domagic_func_t)(...);
domagic_func_t resolve_domagic()
{
__builtin_cpu_init();
if (__builtin_cpu_supports("avx") && __builtin_cpu_supports("fma")) {
return domagic_avx_fma;
}
return domagic_general;
}
void domagic(...) __attribute__ ((ifunc ("resolve_domagic")));
程序.c
void domagic(...);
int main() {
domagic(...);
}
编译
$ gcc -c func_avx_fma.c -o func_avx_fma.o -O3 -mfma -mavx
$ gcc -c func_general.c -o func_general.o -O3
$ gcc -c helper.c -o helper.o
$ ...
此方法在 x86 (x86_64) 上非常有效,但并非所有目标都支持这些帮助程序