为什么在某些情况下仍然在汇编语言中使用条件移动指令(CMOV
)?为什么不使用S{cond}
(如果与零相比,则跳过指令)?与CMOV不同,SKIP没有直接的数据依赖关系(这对流水线有利),并且遵循指令cen是任意的(不仅是条件移动)。当然,它不需要齐平流水线,它只是取消以下指令的写入结果。我注意到的唯一瓶颈可以在以下示例中看到:
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中的常见情况,并且得到了有效解决,因此我认为性能下降不会像条件移动那样高。无论如何,哪里可以预测条件跳转,请使用它。
对不起我的英语。
SLEG R2
是一个条件分支,由一条指令转发。 它可以通过数据依赖(有效地使下一条指令谓词)或分支预测(与任何其他条件分支相同)来实现。
请注意,比较的结果计为"数据",因此cmov
有 3 个输入:dest、src 和 flag。 同样,使用跳过谓词指令会将跳过的控制输入添加到另一个指令的数据依赖项中。
你必须选择一个或另一个。 我认为说出我认为你想说的话的正确方法是,通常数据依赖性检查不会找到它必须等待的任何内容。 在像现代 x86 芯片这样的 4 宽无序设计中,这种情况会更少见,因为数据依赖关系的窗口要大得多。 飞行中的指令还有很多,任何独立的依赖链都可以并行运行。
跳过指令肯定比x86笨拙的cmov
更强大。 由于cmov
不能立即接受操作数,因此通常需要额外的指令才能将常量作为源放入另一个寄存器中。
Paul Clayton 的评论很有趣:POWER8 特殊情况下有条件的 forward-by-1-insn 分支将它们作为数据依赖关系而不是控制依赖关系来处理。 这听起来应该与PIC跳过指令完全相同。