3

This is a theoretical question and I feel stuck.Suppose I take ARM ISA and pipelined datapath. I am using a branch predictor, which for simplicity, always predicts that a branch is taken. As it is evident, it works if the branch was indeed to be taken, but fails otherwise. If it fails, it has to roll back and undo all the changes , i.e. flush the pipeline.

How is it supposed to do so?

What if some value is written to some register?

Then how can I bring that register to its previous value? Same thing goes for flags?

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
Ankit Shubham
  • 2,989
  • 2
  • 36
  • 61
  • 2
    Related: [Does a branch misprediction flush the entire pipeline, even for very short if-statement body?](https://stackoverflow.com/questions/29522431/does-a-branch-misprediction-flush-the-entire-pipeline-even-for-very-short-if-st). As discussed in comments there, one simple technique for flushing is to wait until the mispredicted branch reaches retirement; then the register state there is the correct in-order state you can roll back to. Otherwise you checkpoint the register-renaming state for fast recovery from mispredicts (faster than a full flush like for exceptions). – Peter Cordes Mar 05 '18 at 03:39
  • 2
    Without some kind of rollback / recovery mechanism (usually involving register renaming), you can't do speculative out-of-order execution. **You can fetch/decode based on branch prediction without any special support**, but you can't let any speculative instruction modify the only copy of the architectural state. (as Dric's answer points out, an in-order pipeline can let instructions proceed until the write-back stage. Because it's in-order, we already know that no earlier instruction faulted or was mispredicted). – Peter Cordes Mar 05 '18 at 03:47

1 Answers1

4

As this is defined in the architecture, you will always have the guarantee that if a branch is mispredicted and it has to flush the pipeline, all following instructions cannot have a visible impact on the architecture.

There are several ways to do it: in simple implementation (short pipelines), instructions will generally be committed (i.e. write an architecturally visible modification) when it is guaranteed that it is not in a branch (A load that can fault) shadow anymore.

In more complex CPUs, longer pipelines and out-of-order cores, the technique that is used generally use Register Renaming:

https://en.wikipedia.org/wiki/Register_renaming

In this case, the instructions will be able to complete, write the result to a temporary register or location, and the CPU will have mechanisms to either restore the state (In case of flush) or only commit the temporary results to architectural registers when it has the guaranty these results cannot be flushed anymore.

Greenbeard
  • 508
  • 5
  • 14
Dric512
  • 3,525
  • 1
  • 20
  • 27