英特尔新架构的控制指令和移动指令延迟有哪些?

时间:2018-03-15 18:23:18

标签: x86 intel machine-code micro-architecture

我正在查看Intel Architectures Optimization Reference Manual 2017(第759页)。我正在寻找Haswell和Skylake架构。该表中有意省略MOV, PUSH, JMP, CALL条指令。没有给出延迟信息。这是为什么?虽然,第776页为Atom处理器提供了那些指令延迟。

有趣的是,来自英特尔的2012 optimization manualMOVPUSHCALL指示延迟。

Agner instruction tables提供了MOVPUSH的延迟,但跳过了JMPCALL等控制指令。知道为什么会这样吗?

1 个答案:

答案 0 :(得分:2)

简短的回答是,在实践中,延迟对于控制指令和单独的许多类型的mov指令来说并不是真正有意义的指标。

在你提到的评论中:

  

我指的是英特尔的控制指令手册。我是什么   控制指令的平均延迟意味着我们得到一些   在一段时间内退出的指令数量的数据然后   花时间/(指示数量)。

当我们谈论指令的延迟时,我们通常意味着从输入生成结果的时间,而不是多少结果可以在给定的时间内生产。这需要花费9个月生孩子(延迟)与在一个城市生育100个婴儿(吞吐量)之间的差异。

测量延迟的常用方法是将一系列指令链接在一起,其中一条指令的输出用作下一条指令的输入。由于它们是依赖的,因此它们会因为串行执行而得到延迟测量。例如,如果您想测量add的延迟,您可以使用如下序列:

add eax, eax
add eax, eax
add eax, eax
...

注意输出寄存器eax如何在下一个add的输入中反馈。

现在,控制流指令没有明显的“输出”,可以反馈到输入中。它们的输出是指令流的变化,但不清楚如何将其反馈到下一条指令中。此外,控制流程的整个机制通常被分离成一个分支预测引擎,该分支预测引擎试图在执行控制流程指令之前很长时间正确地操纵前端,当涉及延迟时进一步使水域变得混乱。

充其量你可以谈论这些结构的吞吐量:现代英特尔通常可以每个周期执行两个分支,其中最多可以采用其中一个。

您遇到与内存中的mov指令相同的问题。这里,输出和输入是清楚的,但它们存在于不同的域(寄存器与存储器)。因此,您不必将存储指令的输出提供给后续存储指令,因为存储具有“存储器”输出但是“寄存器”输入。您可以做的是在同一位置将成对的加载和存储指令链接在一起,并获得该对的组合延迟:这通常在现代英特尔上运行3到7个周期,具体取决于寻址模式和其他因素。

对于特定的负载,您可以在地址计算中使用加载结果(寄存器域)来进行下一次加载,从而为您提供加载到加载地址的延迟(有些人将此称为负载使用,但我认为这很令人困惑),现代英特尔通常只有4个周期,复杂的寻址模式或矢量负载需要1个额外的周期。

对于寄存器注册移动,延迟通常为零周期(由于移除消除),或者当mov无法消除时为1个周期。

这些问题可能就是为什么你没有在英特尔指南中看到这些结构的延迟数字,甚至在Agner的其他指南中也没有。