Can someone please help me understand how CMOV improves branching?
Well, it does not improve branching, it removes it. CMOV can be considered as two teams in one, MOV and NOP. Which one is executed depends on the flags. So internally it may look like
if (cond) { mov dst, src } else { nop }
...
Of course, the problem area remains the same - we do not know the address of the next instruction to execute?
Oh no. The next command is always following the CMOV, so the command pipeline is not invalid and reloads (branch rejection and other optimization functions remain on the sidelines). This is one continuous stream of macros. A simple example is as follows
if (ecx==5) eax = TRUE else eax = FALSE
in base 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
with 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
Is it worth it on current processors? Clear YES. In my experience and (of course) depending on the algorithm, the increase in speed is significant and worth the effort.
source share