Reputation: 33627
If I #include <immintrin.h>
I get this error:
error: '__builtin_ia32_addpd256' was not declared in this scope
I have defined __AVX__
and __FMA__
macros to make AVX avilable, but apparently this isn't enough. There is no error if I use compiler flag -mavx
instead of the macros, but that solution is not acceptable. So, what else should I define to use AVX?
Upvotes: 0
Views: 3635
Reputation: 61
The proper solution might be to have a specific file that contains the processor specific intrinsic. And you set -mavx -mfma options only to this file. The program itself determine which version to call at runtime.
I use GCC helpers to get the best optimized version at runtime.
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(...);
}
To compile
$ 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
$ ...
This approach works great on x86 (x86_64) but not all targets support these helpers
Upvotes: 1
Reputation: 213210
You shouldn't be defining __AVX__
and __FMA__
yourself - these get defined automatically when you enable the correct compiler options, e.g.
gcc -Wall -mavx ...
You can check this yourself if you're interested:
No 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
$
Upvotes: 5