针对新指令集扩展优化编译的代码的向后兼容性

Backward compatibility of the code compiled optimized for new instruction set extensions

为了缩小这个问题的范围,让我们只考虑 C / C++ 中的项目。

x86 架构有一整套新的 SIMD 指令集扩展,但为了从中受益,开发人员应该使用适当的优化标志重新编译代码,或许还可以相应地对其进行修改。

由于新的指令集扩展相对频繁地出现,因此不清楚如何在利用可用指令集扩展的好处的同时保持向后兼容性。

生成的应用程序是否与不支持新机构集扩展的旧 CPU 模型保持兼容?如果是,您能否详细说明这种支持是如何实施的?

新 CPU 指令需要新硬件才能执行。如果您尝试在不支持这些指令的旧 CPU 上 运行 它们,您的程序将因无效操作码错误而崩溃。有时操作系统会处理这种情况,但通常不会。

要运行使用新指令,您要么需要硬件支持它们,要么(如果好处足够大)在运行时检查是否有新指令支持您需要的说明。如果是,您 运行 一段使用它们的代码。如果不是,则您 运行 不使用它们的不同代码部分。

一般来说,"backwards compatible" 指的是 运行ning 东西的新版本 运行 旧的、现有的东西,而不是旧的东西 运行 新的东西.

从历史上看,大多数 x86 指令集(实际上)是以前指令集的严格超集。但是,AVX-512 扩展有几个相互不兼容的变体,因此需要特别小心。

幸运的是,编译器也变得越来越聪明。 GCC 有 __attribute__((simd))__attribute__((target_clones(...))) 来自动创建给定函数的 多个 实现,并在加载时根据实际 CPU 支持。 (对于较旧的 GCC 版本,您必须手动使用 IFUNC ...并且在 ancient 天后,ld.so 将从完全独立的目录加载库,具体取决于 cmov).