Compile with AVX2 support and run

2019-08-12 17:25发布

问题:

I have a very big library and I want to compile it with AVX2 support (but my processor supports inly AVX). This library also has internal runtime checks whether a processor support AVX2 or not. Something like this:

#if __AVX2__
if (support_avx2)
{
    // vectorized code
}
#endif
// simple C++ code

I was able to compile the library with AVX2 support, but when I run tests I have got at the very beginning:

Illegal instruction: 4

Any ideas? The goal is to compile the library with all available optimisations and features and check them in runtime.

p.s. I'm working on OSX

回答1:

There is no easy way to run AVX2 code on a CPU that only has AVX (e.g. Sandy Bridge/Ivy Bridge). You could use Intel's SDE to run the code for test purposes (this actually works pretty well, for command-line executables at least), but it might just be easier to get a Haswell Mac for development and testing.



回答2:

Basically you can use cpuid to check whether the cpu supports the feature you want to use, then jump to code using it if it does.

The

#if __AVX2__ 

relates only to the machine on which you are compiling and is usually set by compiler flags.



回答3:

If you only compile for AVX2 your compiler assumes it can use AVX2 when it wants. You have to compile for the lowest common hardware you want to use, then check what hardware is available, and then set your functions to point to appropriate functions from object files compiled with that hardware. This is a CPU dispatcher. Here is a lazy man's dispatcher:

//foo.cpp
#if __AVX2__
void foo_AVX2() {
    //AVX2 code
    //make sure to call zeroupper!!!
}
#else
void foo_AVX2();
void foo() {
    //simple C++ code
}

int main(void) {
    bool support_avx2 = detect_AVX2();
    if (support_avx2) {
        foo_AVX2();
    }
    else {
        foo();
    }
}
#endif

Then compile like this:

g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o
g++ -O3 foo.cpp foo_AVX2.o


标签: macos avx