如果我#include <immintrin.h>
我收到此错误:
错误:未在此范围内声明'__builtin_ia32_addpd256'
我已定义__AVX__
和__FMA__
宏以使AVX可用,但显然这还不够。如果我使用编译器标志-mavx
而不是宏,则没有错误,但该解决方案是不可接受的。那么,我还应该定义什么才能使用AVX?
答案 0 :(得分:5)
您不应该自己定义__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
$
答案 1 :(得分:1)
正确的解决方案可能是拥有一个包含特定于处理器的内在特定文件。并且只将 -mavx -mfma 选项设置为此文件。程序本身确定在运行时调用哪个版本。
我使用GCC帮助程序在运行时获得最佳的优化版本。
func_avx_fma.c
void domagic_avx_fma(...) {}
func_general.c
void domagic_general(...) {}
helper.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")));
program.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)上运行良好,但并非所有目标都支持这些帮助程序