Reputation: 620
One way of doing this would be to create function pointers which conditionally point to different functions depending upon a preprocessor directive which selects the desired feature set.
#if defined(__AVX512__)
void (*func_ptr)() = _mm512_func;
#else
void (*func_ptr)() = _mm256_func;
#endif
int main()
{
func_ptr();
return 0;
}
Are there better ways of doing this? Thanks.
Upvotes: 0
Views: 235
Reputation: 363902
If you're detecting AVX512 only at compile time, you don't need function pointers.
The simplest way: don't define different names for the same function at all, just select which definition to compile in the .cpp
file where you have multiple versions of it. That keeps the compile-time dispatching isolated to the file that defines the function, not visible to the rest of your code.
#ifdef __AVX512F__
void func(float *__restrict a, float *__restrict b) {
... // AVX512 version here
}
#elif defined(__AVX2__) && defined(__FMA__)
void func(float *__restrict a, float *__restrict b) { // same name
... // AVX2 version here
}
#else
... // SSE2 or scalar fallback
#endif
Although for testing you do probably want to be able to build all versions of it and test + benchmark them against each other, so you might consider using #define func _mm512_func
, or using some preprocessor tricks inside that one file. Maybe another answer will have a better idea for this.
I thought function pointers were preferred over macros in the C++ community. But this does the same job
Maybe if the function point is void (*static const func_ptr)()
then you can count on it being inlined / optimized away. You really don't want to add extra overhead for dispatching if you don't need it (e.g. for runtime CPU detection, setting functions pointers in an init function that runs cpuid
)
Upvotes: 3