【问题标题】:What happens when I compile on machine that supports avx2 and run the binary on another machine that only supports avx?当我在支持 avx2 的机器上编译并在另一台只支持 avx 的机器上运行二进制文件时会发生什么?
【发布时间】:2018-12-08 02:59:03
【问题描述】:

我在支持 avx2(Intel E5-2643 V3)的机器上编译了我的 c++ 程序。它编译并运行得很好。我确认使用了 avx2 指令,因为在我分解二进制文件后,我看到了 avx2 指令,例如 vpbroadcastd

然后我在另一台只有 avx 指令集(Intel E5-2643 V2)的机器上运行这个二进制文件。它运行也很好。二进制文件是否在向后兼容的 avx 指令上运行?这个指令是什么?您是否发现任何潜在问题?

【问题讨论】:

  • 我不确定为什么这个问题被否决了。我搜索但找不到答案。我们在哪里可以找到投反对票的原因,以便我们将来改进?

标签: c++ avx avx2


【解决方案1】:

如果实际执行了 AVX2 指令,它会引发 #UD,因此操作系统会将 SIGILL(非法指令)传递给您的进程或 Windows 等效指令。

在某些情况下,像 lzcnt 这样的指令会解码为 rep bsr,而在没有 BMI1 的 CPU 上会以 bsr 的形式运行。 (给出不同的答案)。但是 VEX 编码的 AVX2 指令只会在较旧的 CPU 上出错。


如果程序从不运行包含 AVX2 指令的函数,那么它可能会使用其他输入,或者它可能会执行运行时 CPU 检测。

【讨论】:

  • 奇怪的是二进制文件在没有 AVX2 指令的 CPU 上运行良好。我们没有捕获任何异常并且程序没有错误地完成。对于这条特定的指令VPBROADCASTD,旧 CPU 是否有可能将 VPBROADCASTD 解释为 AVX 指令集中可用的 VBROADCASTSD
  • @werk:不,这是不可能的,就像我说的 VEX 编码指令不是旧操作码前面的新前缀。它们使用不同的操作码和 VEX 前缀中的不同位。唯一的解释是 vpbroadcastd 根本没有执行。 (顺便说一句,vbroadcastss 是等效的,广播 4 个字节,一个 dword。)有趣的事实:即使vbroadcastss/sd 的 reg-reg 形式也需要 AVX2。只有广播加载形式是 AVX1。
  • 如果您不相信,请编辑二进制文件并将vpbroadcastd 替换为ud20F 0B。或者使用int3(调试器断点)。或者更简单地说,在调试器下运行它并在该指令处设置断点,并注意它从未被命中。 (在 GDB 中,b *0x12345 在数字地址处设置断点)。你是用 Intel 的编译器编译的还是运行时 CPU 调度的东西?
  • 你所说的正是我所想的。我刚刚做了双重检查。看起来我们正在使用的 fftw 是用 avx/avx2 编译的。在这个webpage 中它说“启用各种 SIMD 指令集。您需要支持给定 SIMD 扩展的编译器,但 FFTW 将尝试在运行时检测 CPU 是否支持这些扩展。也就是说,您可以使用--enable- 进行编译。 avx 并且代码仍将在没有 AVX 支持的 CPU 上运行。".
  • @werk:库可以像可执行文件一样轻松地将运行时分派到函数的不同版本。 x264 和 x265 等视频编码器也可以做到这一点。 gcc.gnu.org/wiki/FunctionMultiVersioning 是这样做的一种方式,但许多主要库将推出自己的自定义调度。
猜你喜欢
  • 1970-01-01
  • 2018-04-14
  • 2016-09-25
  • 1970-01-01
  • 2020-06-07
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多