最近遇到了一个 lib 库编译的二进制产物在目标机器报 invalid opcode
的问题。导致这个问题的原因是目标机器缺少 AVX-512
相关指令集,而编译机 CPU 指令集版本较高,含有 AVX-512
,且在编译时打开了 O2
选项。
这里有个隐含的信息:GCC 在打开
O2
编译优化选项后,若march
选项1 指定了native
(即本机),GCC 会尽可能使用本机 CPU 所能支持最强大的 SIMD 指令 2。由于编译机版本很高,在这种情况下,-O2 -march=native
所生成的二进制很可能会包含AVX-512
的指令。
由于目标机的 CPU 微架构为 Broadwell,故解决方案是在编译中指定参数 -march=broadwell
。这样 GCC 所生成的二进制产物就不会使用 Broadwell 架构中“不存在”的指令,解决了库文件的 CPU 架构兼容问题。
CPU info
查看当前系统的虚拟化软件:
|
|
Hypervisor vendor
的值即为虚拟化软件。
查看当前 CPU 支持的指令集(Flags):
|
|
flags
为当前 CPU 支持的指令集。上例中可看出该 CPU 支持AVX-512
等指令集。
GCC info
查看当前 GCC 版本。
|
|
查看当前 GCC 所支持的微架构类型 3。
|
|
若需要编译产物使用指定的 CPU 指令集,可以通过对应的 CPU 或扩展的值,使用
march
来实现。如:我们需要编译产物能够在Core2
上运行,则需-march=core2
。
查看当前 GCC 针对本机定义了哪些 SSE / AVX 宏 4。
查看当前 GCC 在本机运行指定编译选项后的实际配置 5。
|
|
寻找二进制库中特殊的指令。
这里我们借助了
opcode
脚本 6 来筛选出Haswell
架构中“不认识”的指令。事实上这个脚本有些老旧,只能支持到 Intel 的 Haswell 微架构。且
cmove
这类操作也不认识,还需根据实际情况查看 Intel 官方的指令集手册 7 来确定是否为问题指令。BTW: elfx86exts 这个项目 8 中包含的指令集架构较新,作者使用 Rust 编写,有条件可以尝试一下
笔者没试过。
x86 Options
https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-march-14 ↩︎Optimize options - Using the GNU Compiler Collection (GCC)
https://gcc.gnu.org/onlinedocs/gcc-3.4.0/gcc/Optimize-Options.html#Optimize%20Options ↩︎What are my available march/mtune options?
https://stackoverflow.com/questions/53156919/what-are-my-available-march-mtune-options ↩︎使用 AVX 系列指令集进行向量化
https://enigmahuang.me/2017/09/29/AVX-SIMD/ ↩︎gcc - How to see which flags -march=native will activate? - Stack Overflow
https://stackoverflow.com/questions/5470257/how-to-see-which-flags-march-native-will-activate ↩︎x86 - How to check if a binary requires SSE4 or AVX on Linux - Kyselejsyreček - Super User
https://superuser.com/a/832440/922081 ↩︎Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 (2A, 2B, 2C & 2D): Instruction Set Reference, A-Z
https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf ↩︎x86 - How to check if a binary requires SSE4 or AVX on Linux - Peter - Super User
https://superuser.com/a/1254953/922081 ↩︎

本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。