Nanashi No Gombe
Nanashi No Gombe

Reputation: 620

How would you write feature agnostic code for both AVX2 and AVX512?

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

Answers (1)

Peter Cordes
Peter Cordes

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

Related Questions