我想知道二进制文件是否使用(编译为)特殊指令集,例如 SSE 4.1/4.2、AVX、F16C。如何查明包中的二进制文件是否使用某些指令集?
我知道configure
在手动编译软件包时我可以使用开关启用此类指令,但是当使用 Debian 存储库中的预编译软件包时,必须有一个默认值。
二进制文件可能不是用太具体的指令集编译的,因为它们不能在任何系统上使用,或者根据二进制文件,它们是用替代子例程编译的,这些子例程“模拟”基本指令的处理以支持缺乏此类功能的 CPU。
我知道我可以查看rules
Debian 源代码包的文件,但我很感兴趣是否有更简单的方法来做到这一点。
- x86-64 二进制文件使用的 CPU 指令是否非常有限?
- 软件包是否可以使用非常具体的指令集,它们是否可以使用更原始的指令进行回退?
答案1
一般性地回答你的问题,https://superuser.com/questions/726395/how-to-check-if-a-binary-requires-sse4-or-avx-on-linux给出一个脚本,可以输入反汇编的二进制文件( 的输出objdump
),并尝试找出所需的最小指令集。这种技术必然是近似的,因为给定的二进制文件可能具有不同的执行路径,具体取决于可用的指令集,并且这样的二进制文件似乎需要它支持的“最佳”指令集,即使它实际上可以在没有它的情况下运行。
特别是关于 Debian 软件包,任何为amd64
(64 位“PC”指令集)打包的内容都必须能够在任何 AMD64 或 x86-64 兼容的 CPU 上运行;这意味着它可以使用完整的标准 64 位指令集,其中包括 SSE2,但如果它为不支持这些功能的 CPU 提供后备功能,则它只能使用其他功能(包括您列出的功能)。也有例外,但包应该在包描述中指出(例如,参见rr
)。
Linux 内核本身可以调整其功能以适应其运行的 CPU 的功能。如果它是为 x86-64 编译的,假设它可以使用 TSC、CMPXCHG64、CMOV(查找依赖于X86_64
该链接的任何内容)。但它可以被编译以在运行时检查 AES-NI、AVX、AVX2 等功能是否可用,并特别使用它们来加速加密计算。这可能会使任何使用这些功能的程序受益(但代价是上下文切换到内核)。
在某些情况下,动态链接器还可以帮助根据 CPU 提供替代方案:因此libc6-i686
为架构提供了一组库,这些库将自动使用,而不是与指令集兼容(并支持 CMOV)的i386
CPU 上的基本等效项。i686