Macos 使用AVX2支持编译并运行

Macos 使用AVX2支持编译并运行,macos,avx,Macos,Avx,我有一个非常大的库,我想用AVX2支持编译它,但我的处理器支持inly AVX。该库还具有内部运行时检查处理器是否支持AVX2。大概是这样的: #if __AVX2__ if (support_avx2) { // vectorized code } #endif // simple C++ code g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o g++ -O3 foo.cpp foo_AVX2.o 我能够使用AVX2支持编译库,但当我运行测试时,我

我有一个非常大的库,我想用AVX2支持编译它,但我的处理器支持inly AVX。该库还具有内部运行时检查处理器是否支持AVX2。大概是这样的:

#if __AVX2__
if (support_avx2)
{
    // vectorized code
}
#endif
// simple C++ code
g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o
g++ -O3 foo.cpp foo_AVX2.o
我能够使用AVX2支持编译库,但当我运行测试时,我从一开始就得到了:

Illegal instruction: 4
有什么想法吗? 目标是编译包含所有可用优化和功能的库,并在运行时检查它们


p、 我正在OSX上工作,在只有AVX的CPU上运行AVX2代码并不容易,例如Sandy Bridge/Ivy Bridge。您可以使用它来运行代码进行测试,这实际上运行得很好,至少对于命令行可执行文件来说是这样,但可能更容易获得Haswell Mac用于开发和测试。

在只有AVX(例如Sandy Bridge/Ivy Bridge)的CPU上运行AVX2代码并不容易。您可以使用它来运行代码以进行测试,这实际上非常有效,至少对于命令行可执行文件来说是这样,但可能更容易获得Haswell Mac用于开发和测试。

基本上,您可以使用cpuid检查cpu是否支持您想要使用的功能,如果支持,则跳转到使用它的代码


仅与正在编译的计算机相关,通常由编译器标志设置。

基本上,您可以使用cpuid检查cpu是否支持您要使用的功能,如果支持,则跳转到使用它的代码


仅与正在编译的计算机相关,通常由编译器标志设置。

如果仅为AVX2编译,则编译器假定它可以在需要时使用AVX2。您必须为要使用的最低通用硬件进行编译,然后检查可用的硬件,然后将函数设置为指向使用该硬件编译的对象文件中的相应函数。这是一个很好的例子。这是一个懒汉的调度员:

//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
然后像这样编译:

#if __AVX2__
if (support_avx2)
{
    // vectorized code
}
#endif
// simple C++ code
g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o
g++ -O3 foo.cpp foo_AVX2.o

如果您只为AVX2编译,那么编译器会假定它可以在需要时使用AVX2。您必须为要使用的最低通用硬件进行编译,然后检查可用的硬件,然后将函数设置为指向使用该硬件编译的对象文件中的相应函数。这是一个很好的例子。这是一个懒汉的调度员:

//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
然后像这样编译:

#if __AVX2__
if (support_avx2)
{
    // vectorized code
}
#endif
// simple C++ code
g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o
g++ -O3 foo.cpp foo_AVX2.o


代码不检查处理器是否支持AVX2。它只检查是否为AVX2设置了编译器选项。您需要的是一个CPU调度程序。这里有几个链接。实际上,support_avx2是一个布尔标志,它反映了一个适当的cpuid位。当你为avx2编译时,你的编译器假设它可以在任何时候使用avx2,例如用于矢量化。您必须为最小公分母进行编译,我猜在您的情况下,您希望为dispatcher支持AVX。然后为每个AVX和AVX2编译单独的对象文件,然后让dispatcher跳转到适当的版本。您的代码不会检查处理器是否支持AVX2。它只检查是否为AVX2设置了编译器选项。您需要的是一个CPU调度程序。这里有几个链接。实际上,support_avx2是一个布尔标志,它反映了一个适当的cpuid位。当你为avx2编译时,你的编译器假设它可以在任何时候使用avx2,例如用于矢量化。您必须为最小公分母进行编译,我猜在您的情况下,您希望为dispatcher支持AVX。然后为每个AVX和AVX2编译单独的对象文件,然后让dispatcher跳转到适当的版本。Intel的SDE易于安装和使用吗?我一直在考虑AVX512。是的,我发现它至少很容易安装在OS X上-我想Linux应该没有问题,而且它工作得很好-只有不受支持的指令被模拟,其他一切都以全速运行,因此,它不会受到CPU模拟器的常见问题的影响,在这种情况下,您会发现自己的运行速度比实际CPU慢几个数量级。@PaulR,给定一个DLL/Dylib/O,有没有办法知道它需要哪些指令集?谢谢。@Royi:我想你可以通过反汇编程序运行它,并对输出进行grep,以获得特定的指令。没有任何工具或类似的东西可以自动完成这项工作?英特尔的SDE易于安装和使用吗?我一直在考虑AVX512。是的,我发现它至少很容易安装在OS X上-我想Linux应该没有问题,而且它工作得很好-只有不受支持的指令被模拟,其他一切都以全速运行,因此,它不会受到CPU模拟器的常见问题的影响,在这种情况下,您会发现自己的运行速度比实际CPU慢几个数量级。@PaulR,给定一个DLL/Dylib/O,有没有办法知道它需要哪些指令集?谢谢。@Royi:我想你可以通过一个反汇编程序运行它,并对输出进行grep,以获得特定的指令。没有工具或类似的东西可以自动完成这项工作?实际上,支持avx2
是一个布尔标志,它反映了一个适当的cpuidWell位。如果您像您所说的那样得到一条非法指令,那么它可能没有按照您所认为的方式工作。我建议在gdb下运行它,然后进行反汇编,这样你就可以看到确切的非法指令和它的来源,然后从那里向后工作,找到你的bug。实际上,support_avx2是一个布尔标志,它反映了一个适当的CPUIDELL位。如果您像您所说的那样得到一条非法指令,它可能没有按照您所认为的方式工作。我建议在gdb下运行它,然后进行反汇编,这样您就可以看到确切的非法指令以及它的来源,然后从那里向后工作以找到您的bug。