我知道当一个分支很容易预测时,最好使用 IF 语句,因为该分支是完全免费的。我了解到,如果分支不容易预测,那么 CMOV 会更好。但是,我不太明白如何实现这一点?
当然,问题域仍然是相同的——我们不知道下一条要执行的指令的地址?所以我不明白在执行 CMOV 时,如何一路向下流水线,这如何帮助指令提取器(过去 10 个 CPU 周期)选择正确的路径并防止流水线停顿?
有人可以帮我了解 CMOV 如何改进分支吗?
最佳答案
Could somebody please help me understand how CMOV improves branching?
好吧,它不会改善分支,它会删除它。 CMOV 可以看作是两条指令合二为一,一条 MOV 和一条 NOP。执行哪一个取决于标志。所以在内部它可能看起来像
if (cond) {
mov dst, src
} else {
nop
}
...
Surely the problem domain is still the same- we do not know the address of the next instruction to execute?
嗯,不。下一条指令始终是 CMOV 之后的指令,因此指令流水线不会失效和重新加载(分支预测和其他优化暂且不谈)。它是宏操作码的一个连续流。一个简单的例子如下
if (ecx==5)
eax = TRUE
else
eax = FALSE
在基本汇编中:
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 上值得吗?一个明确的"is"。根据我的经验和(当然)取决于算法,速度提升是显着的,值得付出努力。
关于assembly - 提高 CPU 流水线性能的 CMOV 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27136961/