【问题标题】:Fast hardware integer division快速硬件整数除法
【发布时间】:2022-01-05 00:24:24
【问题描述】:

整数除法的硬件指令历来非常缓慢。例如,对于 64 位输入,Skylake 上的 DIVQ 延迟为 42-95 个周期 [1](倒数吞吐量为 24-90)。

但是有更新的处理器,性能要好得多:Goldmont 的延迟为 14-43,Ryzen 的延迟为 14-47 [1],M1 显然具有“每分频 2 个时钟周期的吞吐量”[2],甚至 Raspberry Pico具有“每个内核的 8 周期有符号/无符号除法/模电路”(尽管这似乎适用于 32 位输入)[3]。

我的问题是,发生了什么变化?是否发明了一种新算法?无论如何,新处理器使用什么算法进行除法?

[1]https://www.agner.org/optimize/#manuals
[2]https://ridiculousfish.com/blog/posts/benchmarking-libdivide-m1-avx512.html
[3]https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__divider.html#details

【问题讨论】:

    标签: performance x86 arm cpu-architecture integer-division


    【解决方案1】:

    在 Ice Lake 之前的 Intel 上,64 位操作数大小是一个异常值,比整数除法的 32 位操作数大小慢得多。 div r32 是 10 uop,最坏情况延迟为 26 个周期,但吞吐量为 6 个周期。 (https://uops.info/https://agner.org/optimize/Trial-division code runs 2x faster as 32-bit on Windows than 64-bit on Linux有详细探索。)

    除法单元的构建方式没有根本变化,只是将硬件除法器加宽到不需要扩展精度的微码。 (英特尔拥有fast-ish dividers for FP 的时间要长得多,这基本上是同样的问题,只是只有 53 位而不是 64 位。FP 除法的难点是尾数的整数除法;减去指数很容易,并且可以并行完成。)

    增量更改是诸如扩大基数以处理每一步的更多位。例如,在初始(表查找?)值之后流水线化细化步骤,以提高吞吐量而不是延迟。


    相关:



    在历史上,除法单元通常根本没有流水线,因为这很困难,因为它需要复制大量的门,而不是在相同的乘数上进行迭代,我认为。而且大多数软件通常会避免(或避免)整数除法因为它在历史上非常昂贵,至少它很少这样做以至于不会从具有相同延迟的高吞吐量除法器中受益匪浅。

    但随着更宽的 CPU 流水线和更高的 IPC 缩小了部门之间的周期差距,这样做更值得。同样,由于晶体管预算巨大,如果对少数程序非常有帮助,那么在大多数程序中会长时间闲置的东西上花费大量时间仍然是有意义的。 (如更广泛的 SIMD 和专门的执行单元,如 x86 BMI2 pdep / pext)。 Dark silicon 是必要的,否则芯片会融化;功率密度是一个很大的问题,请参阅Modern Microprocessors: A 90-Minute Guide!

    此外,越来越多的软件是由对性能一无所知的人编写的,以及更多避免编译时常量以支持灵活的代码(函数参数最终来自某个配置选项),我会猜想现代软件不会像旧程序那样避免分裂。

    浮点除法通常比整数更难避免,因此绝对值得拥有快速的 FP 除法器。如果没有专用的整数除法单元,整数可以从低 SIMD 元素借用尾数除法器。

    因此,FP 动机很可能是英特尔改进吞吐量和延迟划分的实际驱动力,尽管他们在 Ice Lake 之前留下了具有垃圾性能的 64 位整数除法。

    【讨论】:

    • 我不知道整数除法在英特尔上的成本很高。 32bit arm 没有任何div 指令,32bit 的软件例程需要 23 个周期。 (加上函数调用开销)我认为“arm 不需要 div 指令”的说法是一个糟糕的借口,但事实并非如此。
    • @Jake'Alquimista'LEE:一些轻量级 ARM CPU 没有 div 指令,但 cortex-a 内核有 sdivudiv。 (以及从中获得余数的 mul-subtract 指令)例如godbolt.org/z/hbG81zj8Y。 (拥有一个只有几个微指令的div 允许围绕它执行 OoO 执行。这就是英特尔没有像对整数那样对 FP 除法进行微编码的原因之一,尽管即使整数 div 在 Skylake 上的前端成本也不算太高与执行单元的延迟和吞吐量相比,在 10 微秒时差。)
    • 感谢您的回答,非常有趣且内容丰富(一如既往)!但我不太相信它可以解释它。你肯定比我更了解,但“增量更改”是否有可能带来 3 倍的速度提升?仅通过增量更改,M1 是否比 Cascade Lake Xeon 快 10 倍?而 Pico 甚至没有 FP 单元,但仍然分为 8 个周期。并且会假设在各种微架构中增量变化会很明显,但 Cannon Lake 突然变得更快了。 PS:你所说的“扩展精度微码”是指英特尔的 80 位数学(如long double)?
    • 另外,在uops.info 上,我注意到一些奇怪的事情:一些较新的架构没有 DIV 的可变延迟。知道为什么会这样吗?难道仅此一项就意味着对分隔线进行更彻底的改变吗?
    • @Jake'Alquimista'LEE 你能指点我那个“23个周期”的软件模拟部门吗?
    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 2014-08-02
    • 2018-02-26
    • 1970-01-01
    相关资源
    最近更新 更多