在某些情况下,为什么仍然在汇编语言中使用条件移动指令(CMOV
)?为什么不使用S{cond}
(如果与零比较则跳过指令)?与CMOV不同,SKIP不具有直接数据依赖性(这有利于流水线操作),并且后续指令可以是任意的(不仅是条件移动)。当然,它不需要刷新流水线,它只是取消了后续指令的写入结果。我注意到的唯一瓶颈可以在以下示例中看到:
if(a > b) {
a = b;
}
c = a % 2;
程序集等效:
; R0 = a, R1 = b, R2 = c
SUB R2, R0, R1 ; R2 = R0 - R1
SLEG R2 ; if(R0 <= 0) PC++ | Skip If Less or Equal Zero
CP R0, R1 ; R0 = R1
*AND R2, R0, =1 ; R2 = R0 & 0x01
*关键执行。处理器必须等待CP
指令的结果,因为R0
作为AND
指令中的操作数。另一方面,这是现代CPU中的常见情况并且有效地解决了,因此我认为性能的下降不会像在条件移动的情况下那么高。无论如何,可以预测可预测的条件跳转,使用它。
抱歉我的英文。
答案 0 :(得分:1)
function toUpperCase() { [native code] }
是一条指令转发的条件分支。它可以用数据依赖(有效地使下一条指令断言)或分支预测(与任何其他条件分支一样对待)来实现。
请注意,比较结果计为&#34;数据&#34;,因此SLEG R2
有3个输入:dest,src和flags。类似地,用跳过来预测指令会将跳过的控制输入添加到另一条指令的数据依赖性中。
你必须选择其中一个。我认为正确的方式来说出我认为你想要说的是通常数据依赖性检查没有找到它必须等待的任何东西。在现代x86芯片这样的4宽无序设计中,这种情况会更少发生,因为数据依赖性的窗口要大得多。飞行中有更多的指令,任何独立的依赖链都可以并行运行。
跳过指令肯定比x86的笨重cmov
更强大。由于cmov
不能立即采用操作数,因此通常需要额外的指令将常量放在另一个寄存器中作为源。