使用 AVX2 支持编译并运行
Posted
技术标签:
【中文标题】使用 AVX2 支持编译并运行【英文标题】:Compile with AVX2 support and run 【发布时间】:2015-01-06 00:02:15 【问题描述】:我有一个非常大的库,我想用 AVX2 支持编译它(但我的处理器只支持 AVX)。该库还具有内部运行时检查处理器是否支持 AVX2。像这样的:
#if __AVX2__
if (support_avx2)
// vectorized code
#endif
// simple C++ code
我能够编译支持 AVX2 的库,但是当我运行测试时,我在一开始就得到了:
Illegal instruction: 4
有什么想法吗? 目标是编译包含所有可用优化和功能的库,并在运行时检查它们。
附言我在 OSX 上工作
【问题讨论】:
您的代码不会检查您的处理器是否支持 AVX2。它只检查是否为 AVX2 设置了编译器选项。你想要的是一个 CPU 调度程序。这是preventing-gcc-from-automatically-using-avx-and-fma-instructions-when-compiled-w的几个链接。 实际上,support_avx2 是反映适当位 cpuid 的布尔标志。 当您为 AVX2 编译时,您的编译器假定它可以随时使用 AVX2(例如用于矢量化)。你必须编译你想要支持调度程序的最低公分母(我猜你的情况是 AVX)。然后为每个 AVX 和 AVX2 编译单独的目标文件,然后让调度程序跳转到适当的版本。 【参考方案1】:没有简单的方法可以在只有 AVX 的 CPU(例如 Sandy Bridge/Ivy Bridge)上运行 AVX2 代码。您可以使用 Intel's SDE 来运行代码以进行测试(这实际上工作得很好,至少对于命令行可执行文件),但使用 Haswell Mac 进行开发和测试可能更容易。
【讨论】:
英特尔的 SDE 是否易于安装和使用?我一直在为 AVX512 考虑它。 是的,我发现它很容易安装(至少在 OS X 上 - 我想 Linux 应该没问题)而且效果很好 - 只有不受支持的指令被模拟,其他一切都全速运行,因此它不会遇到 CPU 模拟器常见的问题,即您发现自己的运行速度比在真实 CPU 上慢几个数量级。 @PaulR,给定一个 DLL / Dylib / O,有没有办法知道它需要哪些指令集?谢谢。 @Royi:我想你可以通过反汇编程序运行它并 grep 输出以获取特定指令。 没有工具或类似的东西可以自动执行此操作吗?【参考方案2】:基本上你可以用cpuid来检查cpu是否支持你要使用的特性,如果支持就跳转到使用它的代码。
#if __AVX2__
仅与您正在编译的机器有关,通常由编译器标志设置。
【讨论】:
实际上,support_avx2 是反映适当位 cpuid 的布尔标志 好吧,如果你收到了你所说的非法指令,它可能不会像你想象的那样工作。我建议在 gdb 下运行它然后反汇编,这样你就可以看到精确的非法指令以及它的来源,然后从那里向后工作以找到你的错误。【参考方案3】:如果您只为 AVX2 编译,您的编译器会假定它可以在需要时使用 AVX2。您必须针对要使用的最低通用硬件进行编译,然后检查可用的硬件,然后将函数设置为指向使用该硬件编译的目标文件中的适当函数。这是CPU 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
然后像这样编译:
g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o
g++ -O3 foo.cpp foo_AVX2.o
【讨论】:
以上是关于使用 AVX2 支持编译并运行的主要内容,如果未能解决你的问题,请参考以下文章
如果我使用 AVX2 创建应用程序,它会在其他机器上运行吗?
“您的 CPU 支持未编译此 TensorFlow 二进制文件以使用的指令:AVX2”错误
您的 CPU 支持未编译此 TensorFlow 二进制文件以使用的指令:AVX AVX2