gpt4 book ai didi

performance - 6 种基本算术运算的相对循环时间是多少?

转载 作者:行者123 更新时间:2023-12-03 16:22:34 24 4
gpt4 key购买 nike

当我尝试优化我的代码时,很长一段时间我一直在使用一个经验法则,即加法和减法值 1,乘法和除法值 3,平方值 3(我很少使用更通用的 pow函数,所以我没有经验法则),平方根值 10。(我假设平方只是乘法,所以值 3。)

这是 2D 轨道模拟的示例。为了计算和应用重力加速度,首先我得到从船到地心的距离,然后计算加速度。

D = sqrt( sqr(Ship.x - Earth.x) + sqr(Ship.y - Earth.y) ); // this is worth 19
A = G*Earth.mass/sqr(D); // this is worth 9, total is 28

但是,请注意,在计算 D 时,取平方根,但在下一次计算中使用它时,取平方。因此,您可以这样做:
A = G*Earth.mass/( sqr(Ship.x - Earth.x) + sqr(Ship.y - Earth.y) ); // this is worth 15

因此,如果我的经验法则是正确的,我几乎将周期时间缩短了一半。

然而,我什至不记得我以前在哪里听说过这个规则。我想问一下这些基本算术运算的实际循环时间是多少?

假设:
  • 在 x64 架构中,一切都是 64 位浮点数。
  • 一切都已经加载到寄存器中,所以不用担心缓存或内存的命中和未命中。
  • 没有对 CPU 的中断
  • 没有 if/branching 逻辑,例如前瞻预测

  • 编辑: 我想我真正想做的是 查看 ALU 内部,并且只计算 6 个操作的逻辑循环时间。如果其中仍然存在差异,请解释是什么以及为什么。

    注意: 我没有看到机器码的任何标签,所以我选择了下一个最接近的东西,汇编。需要明确的是,我说的是 x64 架构 中的 实际机器码操作。因此,我编写的这些代码行是否使用 C#、C、Javascript 或其他语言都没有关系。我相信每种高级语言都会有自己不同的时间,所以我不想就此争论不休。我认为没有机器代码标签是一种耻辱,因为在谈论性能和/或操作时,您确实需要深入研究。

    最佳答案

    至少,人们必须了解一项操作至少有两个有趣的时间点:延迟和吞吐量。

    潜伏

    延迟是任何特定操作从输入到输出所需的时间。如果您有一系列操作,其中一个操作的输出被馈送到下一个操作的输入,则延迟将决定总时间。例如,最新的 x86 硬件上的整数乘法有 3 个周期的延迟:完成一个乘法运算需要 3 个周期。整数加法有 1 个周期的延迟:结果在加法执行后的周期可用。延迟通常是正整数。

    吞吐量

    吞吐量是单位时间内可以执行的独立操作的数量。由于 CPU 是流水线和超标量的,这通常不仅仅是延迟的倒数。例如,在最新的 x86 芯片上,即使延迟为 1 个周期,每个周期也可以执行 4 个整数加法运算。类似地,平均每个周期可以执行 1 个整数乘法,即使任何特定的乘法需要 3 个周期才能完成(这意味着您必须同时进行多个独立的乘法才能实现这一点)。

    逆吞吐量

    在讨论指令性能时,通常将吞吐量数字表示为“逆吞吐量”,即 1 / throughput .这使您可以轻松地直接与延迟数据进行比较,而无需在脑海中进行划分。例如,加法的逆吞吐量为 0.25 个周期,而延迟为 1 个周期,因此您可以立即看到,如果您有足够多的独立加法,它们每个只使用 0.25 个周期。

    下面我将使用逆吞吐量。

    可变时间

    大多数简单的指令都有固定的时间,至少在它们的 reg-reg 形式中。然而,一些更复杂的数学运算可能具有依赖于输入的时序。例如,加法、减法和乘法通常在整数和浮点形式上有固定的时序,但在许多平台上,除法在整数、浮点或两者上都有可变的时序。 Agner 的数字通常会显示一个范围来表示这一点,但您不应假设操作数空间已经过广泛测试,尤其是对于浮点数。

    例如,下面的 Skylake 数字显示的范围很小,但不清楚这是由于操作数依赖性(可能会更大)还是其他原因。

    根据非正规模式,传递非正规输入或本身非正规的结果可能会产生显着的额外成本。您将在指南中看到的数字通常假定没有异常值,但您可以在别处找到有关每次操作的异常成本的讨论。

    更多细节

    以上信息对于完全限定性能而言是必要的,但通常不是足够的信息,因为您还有其他因素需要考虑,例如执行端口争用、前端瓶颈等。不过,开始就足够了,如果我理解正确,您只是要求“经验法则”数字。

    阿格纳雾

    我推荐的测量延迟和逆吞吐量数字的来源是 Agner's Fogs guides .您想要 下的文件4. 指令表:Intel、AMD 和VIA CPU 的指令延迟、吞吐量和微操作故障列表 ,其中列出了各种 AMD 和 Intel CPU 上相当详尽的时序。您也可以直接从 Intel 的指南中获取某些 CPU 的编号,但我发现它们不如 Agner 的指南完整且更难使用。

    下面我将列出几个现代 CPU 的数字,用于您感兴趣的基本操作。

    英特尔天湖

                             Lat  Inv Tpt
    add/sub (addsd, subsd) 4 0.5
    multiply (mulsd) 4 0.5
    divide (divsd) 13-14 4
    sqrt (sqrtpd) 15-16 4-6

    因此,延迟的“经验法则”将是 add/sub/mul all cost 1,并且除法和 sqrt 分别约为 3 和 4。对于吞吐量,规则分别为 1、8、8-12。另请注意,延迟远大于反向吞吐量,特别是对于 add、sub 和 mul:如果您想达到最大吞吐量,则需要 8 个并行操作链。

    AMD锐龙
                             Lat  Inv Tpt
    add/sub (addsd, subsd) 3 0.5
    multiply (mulsd) 4 0.5
    divide (divsd) 8-13 4-5
    sqrt (sqrtpd) 14-15 4-8

    锐龙的数字与最近的英特尔大致相似。加法和减法的延迟稍低,乘法是一样的。在延迟方面,经验法则通常仍可概括为 add、sub、mul/div/sqrt 的 1/3/4,但精度有所损失。

    在这里,除法的延迟范围相当大,所以我预计它取决于数据。

    关于performance - 6 种基本算术运算的相对循环时间是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46505827/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com