Если я #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(...) {}
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), но не все цели поддерживают эти помощники