为什么 Clang 只从 Sandy Bridge 开始执行此优化技巧?

问题描述 投票:0回答:1

我注意到 Clang 对以下代码片段做了一个有趣的除法优化技巧

int64_t s2(int64_t a, int64_t b)
{
    return a/b;
}

如果将

march
指定为 Sandy Bridge 或以上,则以下是装配输出

        mov     rax, rdi
        mov     rcx, rdi
        or      rcx, rsi
        shr     rcx, 32
        je      .LBB1_1
        cqo
        idiv    rsi
        ret
.LBB1_1:
        xor     edx, edx
        div     esi
        ret

这里是签名版本未签名版本

的Godbolt链接

据我了解,它检查两个操作数的高位是否为零,如果为零则进行 32 位除法

我检查了此表,发现 Core2 和 Nehalem 上 32/64 位除法的延迟分别为 40/116 和 26/89。因此,如果操作数确实通常不宽,那么通过进行 32 位除法而不是 64 位除法所节省的成本可能与 SnB 一样有价值

那么为什么它只针对 SnB 和更高版本的微架构启用呢?为什么其他编译器(例如 GCC 或 ICC)不这样做?

assembly optimization clang x86-64 division
1个回答
6
投票

我猜测 clang 开发者测试了它适用于哪些 uarch,并发现它只是 SnB 系列。

这听起来不错,因为 P6 系列上有一个时髦的档位,以及 AMD 不同的分隔符。


在 P6 系列上使用移位 imm8(不是隐式移位 1)的标志结果会导致前端在发出标志读取指令之前停止,直到移位“退休”。 (因为 P6 解码器不会检查 imm8=0 的情况以保持标志未修改,而 SnB 会检查)。 INC 指令与 ADD 1:这重要吗?。 这可能就是 clang 不将它用于 P6 系列的原因。

可能有一种不同的方法来检查不会导致此停顿的相关条件(例如在

test rcx,rcx 之前使用

je
,这在 Core2/Nehalem 上是值得的)。
 但如果 clang 开发人员没有意识到P6 系列上速度缓慢的原因是他们不会考虑修复它,只是没有为 SnB 之前的目标完成它。  (不幸的是,没有人将我添加到有关此问题的补丁审查或 bug CC 列表中;这是我第一次看到 clang 进行此优化。尽管我认为我可能在其他一些 LLVM 审查或评论中提到了移位标志停顿无论如何,尝试添加 
test
并看看这是否值得在 Nehalem 上使用可能会很有趣。)

根据 Agner Fog 的说法,无论操作数大小如何,AMD 的除法器都具有相同的最佳情况除法性能,大概仅取决于输入的实际大小。 只有最坏的情况会随着操作数的大小而增长。
所以我

认为在AMD上以符号扩展至128/64位的小输入运行idiv r64是无害的。

(AMD上的div/idiv对于所有操作数大小都是2微指令(除了8位,它是1)因为它只需要写入一个输出寄存器:AH 和 AL = AX,这与 Intel 的微编码整数除法不同。)
Ice Lake 之前的英特尔

非常

不同:idiv r32为 9 uops,而

idiv r64
为 59 uops,在 Haswell 上,最佳情况吞吐量要差 3 倍。 SnB 系列的其他成员,直至 Skylake 及其衍生产品(如 Cascade Lake)都是类似的。
Ice Lake 添加了一个新的整数除法单元,以与 

idiv r64

相同的 uops 数量处理

idiv r32
,因此在该处理器和较新的 Intel 上,对于相同的输入数,可能具有相同的性能,至少对于混合 CPU,如 Alder Lake。 (对于
idiv r64
,其输入可以适合 i64 被除数和 i32 除数)。
相关:

  • 试除代码在 Windows 上的 32 位运行速度比在 Linux 上的 64 位运行速度快 2 倍
  • 在某些情况下,128 位/64 位硬件无符号除法能否比 x86-64 Intel/AMD CPU 上的 64 位/32 位除法更快?
为什么其他编译器(如 GCC 或 ICC)不这样做?

可能是因为 Clang 开发者想到了这一点,而 GCC/ICC 还没有复制它们。 如果您看过 Chandler Carruth 关于
perf

的演讲,他使用的一个例子是摆弄一根树枝来跳过

div
。 我猜这个优化是他的主意。 看起来很漂亮。 :)
    

© www.soinside.com 2019 - 2024. All rights reserved.