c 中的 x64 内联汇编以对齐指令

x64 inline assembly in c to align instructions

我有一个非常热的指令循环,需要在 32 字节边界上正确对齐以最大化 Intel's Instruction Fetcher 有效性。

此问题特定于英特尔不太旧的 CPU 系列(从 Sandy Bridge 开始)。未能正确对齐循环的开头会导致高达 20% 的速度损失,这绝对是太明显了。 这个问题很少见,需要一组高度优化的指令才能使指令获取器成为瓶颈。但幸运的是,这不是个案。下面是 nice article explaining in details 如何检测此类问题。

问题是,gcc 和 clang 都不会关心正确对齐这个指令循环。它使编译此代码成为产生随机结果的噩梦,这取决于 "good" 热循环如何偶然对齐。这也意味着修改一个完全不相关的函数 none 会严重影响热循环的性能。

已经尝试了几个编译器标志,其中 none 个给出了令人满意的结果。

[编辑] 尝试过的编译标志的更详细描述:

只有使用 PGO 构建才能可靠地产生预期的性能,但 PGO 不能作为解决方案被接受,因为这段代码将使用自己的构建链集成到其他程序中。

所以,我正在考虑内联汇编。 这将特定于 x64 指令集,因此不需要可移植性。

如果我的理解是正确的,像 NASM 这样的汇编允许使用诸如 ALIGN 32 这样的语句,这将强制下一条指令在 32 字节边界上对齐。

由于目标源代码是用C语言编写的,因此有必要包含此语句。例如,类似 asm("ALIGN 32"); (这当然行不通)。

我希望这主要是了解正确的编写指令的问题,而不是诸如 "it's impossible" 之类的更深层次的问题。

与NASM类似,GNU汇编器支持.align伪OP对齐:

volatile asm (".align 32");

对于非汇编解决方案,您可以尝试提供 -falign-loops=32,并可能根据需要提供 -falign-functions=32-falign-jumps=32