什么是CMOV提高CPU流水线性能?

时间:2014-11-25 21:24:21

标签: assembly x86 branch cpu-architecture

我理解当分支很容易预测时,使用IF语句会更好,因为分支是完全免费的。我已经了解到,如果不容易预测分支,那么CMOV会更好。但是,我不太明白这是如何实现的?

问题域肯定是一样的 - 我们不知道下一条指令的执行地址?所以我不明白管道的所有方式,当CMOV执行时,它如何帮助指令获取器(过去10个CPU周期)选择正确的路径并防止管道停滞?

有人可以帮我理解CMOV如何改进分支?

2 个答案:

答案 0 :(得分:8)

CMOV指令不指导控制流的路径。它们是被执行以基于条件代码(即,预测指令)计算结果的指令。某些体系结构(如ARM)可以基于条件代码来预测多种形式的指令,但x86只能执行“mov”,即条件移动(CMOV)。这些被解码,并以延迟执行,以确定指令的结果。

另一方面,分支机构被预测并实际上指导执行指令。分支预测器“向前看”指令“fetcher”,特别是寻找分支指令,并通过引导流来预测路径。想象一下铁路轨道,前方人员向左或向右移动轨道,告诉火车去哪里。现在,如果这个人选择了错误的方向,火车必须停下来,备份,然后再朝正确的方向移动。浪费了很多时间。

另一方面,CMOV不会引导流动。它们只是指令需要额外的时间(并创建额外的依赖关系),以根据条件代码确定移动的正确结果。想想火车,而不是决定左转或右转,采取直线路径,不需要转弯,但有点慢(显然更复杂,但它是我现在能想到的最好的)。

CMOV曾经非常糟糕(非常高的延迟),但后来改进得非常快,使它们更具可用性和性能。

希望这会有所帮助..

答案 1 :(得分:6)

  

有人可以帮我理解CMOV如何改进分支?

嗯,它不会改善分支,它会删除它。 CMOV可以被视为一个中的两个指令,MOV和NOP。执行哪一个取决于标志。所以内部可能看起来像

if (cond) {
    mov dst, src
} else {
    nop
}

...

  

问题域肯定是一样的 - 我们不知道下一条指令的执行地址?

嗯,不。下一条指令始终是CMOV之后的指令,因此指令流水线不会失效并重新加载(分支预测和其他优化保留在一边)。它是宏观操作的一个连续流程。

就是一个简单的例子
if (ecx==5)
    eax = TRUE
else
    eax = FALSE

在基本的asm中:

cmp ecx,5      ; is ecx==5
jne unequal    ; what is the address of the next instruction? conditional branch
mov eax,TRUE   ; possibility one
jmp fin
unequal:       : possibility two
mov eax,FALSE
fin:
nop

使用CMOV

cmp ecx,5
mov eax, FALSE   ; mov doesn't affect flags
mov ebx, TRUE    ; because CMOV doesn't take immediate src operands, use EBX for alternative
cmove eax, ebx   ; executes as MOV if zero-flag is set, otherwise as NOP
nop              ; always the next instruction, no pipeline stall

在当前的CPU上是否值得?一个明确的是。根据我的经验和(当然)取决于算法,速度增益是重要的,值得努力。