2

我知道他们只能在重新排序缓冲区中的指令被提交之前正确执行。我的疑问是,现代处理器是否将它们保留到最后一个 ROB 或是否使用任何预测计数器/结构甚至用于预测标志值,例如零标志或进位标志,然后如果它们被错误预测,则重做它们

4

1 回答 1

4

我知道他们只能在重新排序缓冲区中的指令被提交之前正确执行。

不,他们只需要准备好自己的输入:那些特定的先前指令已执行,而不是退休/提交。

条件移动指令(和 ARM 谓词执行)将标志输入视为数据依赖项,就像 add-with-carry 或整数输入寄存器一样。在所有 3 个输入都准备好1之前,不能将条件指令发送到执行单元。(或者在 ARM 上,标志 + 谓词指令通常具有的许多输入。)

与控制依赖项(分支)不同,它们不会预测或推测标志将是什么,因此 acmovcc而不是 ajcc可以创建循环携带的依赖链并最终比可预测的分支更糟糕。 gcc 优化标志 -O3 使代码比 -O2 慢就是一个例子。

Linus Torvalds 更详细地解释了为什么 cmov 经常很糟糕:https ://yarchive.net/comp/linux/cmov.html

(ARM 谓词执行的处理方式可能略有不同。它必须在逻辑上 NOP 指令,即使加载或存储到无效地址也是如此。这可能只通过条件加载的故障抑制来处理。我不知道一条指令是否带有错误的谓词仍然会花费目标寄存器的依赖链中的任何延迟。)


脚注 1:这就是为什么在 Broadwell 之前英特尔cmovccadc2 个微指令:单个微指令不能有 3 个输入依赖项。Haswell 为 FMA 引入了对 3 输入微指令的支持。

cmov读取 CF 和 SPAZO 标志之一(即读取 CF 和 ZF)的指令cmova实际上cmovbe仍然是 Skylake 上的 2 微指令。有关详细信息,请参阅此问答:这两个单独重命名的标志组似乎都是单独的输入,避免了标志合并。另请参阅https://uops.info/了解 uop 计数。

另请参阅http://agner.org/optimize/https://stackoverflow.com/tags/x86/info以了解有关 x86 微架构详细信息和优化指南的更多信息。

于 2018-06-21T04:20:41.710 回答