问题描述:

In x86-64, if you use the following assembly code:

MOV RAX, (memory address)

JMP RAX

Does the pipeline stall before executing the branch (to wait for MOV to finish with RAX), or will it flush the pipeline like a conditional branch?

网友答案:

For most modern 80x86 CPUs; there's static prediction (no history to use to make a better prediction) and dynamic prediction (where there's history from previous executions that can be used).

For static prediction CPU predicts that execution will continue at the instruction immediately after the JMP RAX. I'm not entirely sure which CPUs use dynamic prediction for JMP RAX (rather than only for the Jc branches); but for those that do it'd override the static prediction.

Once the CPU has a predicted target address, it speculatively executes until it finds out if it predicted right/wrong. If it predicted right it keeps all the work it did and the JMP RAX would have little or no cost.

If CPU predicted wrong then that's no different to any other branch misprediction (discard all the work that was speculatively executed and go back to fetch/decode at the correct RIP).

Note that if your JMP RAX is unpredictable or it's too unlikely that the instruction after it is going to be the target of the jump; Intel recommends putting a PAUSE or UD2 immediately after the jump to prevent unnecessary speculative execution. In this case the CPU would stall (do nothing until it finds out the correct jump target).

Also note that you'd want to move the MOV RAX, .. so that it's executed as soon as possible, so that the target of the jump is known as soon as possible, so that you minimise the time spent stalled or speculatively executing the wrong thing.

相关阅读:
Top