riscv-software-src / riscv-perf-model

Example RISC-V Out-of-Order/Superscalar Processor Performance Core and MSS Model
Apache License 2.0
117 stars 43 forks source link

Initial implementation of branch prediction using a BTB #124

Closed danbone closed 6 months ago

danbone commented 7 months ago

Attempting to add some branch prediction logic to Olympia. I started with a branch target buffer.

Plan is to add a simple predictor, and a return address stack next. As this will require some form of recovery following speculative updates. Forming a foundation for further branch prediction modelling.

Early branch misprediction recovery could be done at a later date, but will require some more complex mechanism for restoring rename map before restarting.

Few points of interest:

klingaard commented 7 months ago

This is awesome! Thanks for putting this together. I'll check it out in more detail in a bit. I did take a few minutes at lunch to address your first POI:

Adding flushing on misprediction has pushed the runtime up considerable, dhrystone takes 250s+

I ran your branch through Apple's Instruments and found that Rename::scheduleRenaming is taking a huge amount of time. I added an assert on the size of uop_queeu_regcount_ data structure to make sure it doesn't grow big. It does! I think this data structure is not being cleared out properly on a flush. @AaronGChan you might need to add this assert to make sure folks update Rename on flush situations.

klingaard commented 7 months ago

Yeah, if you add (untested) this line to the bottom of Rename::handleFlush_ performance goes back to normal:

uop_queue_regcount_data_.clear();
arupc commented 7 months ago

Thank you for initiating this.

To provide more history, per previous discussion, we intend to add branch prediction support via an API, along with an implementation of simple branch predictor. This would enable use of a simple predictor while allowing for implementation of other predictors. There's also an interest in re-using existing branch predictor implementations

Please see https://github.com/riscv-software-src/riscv-perf-model/issues/1

I will start a discussion item on this topic. Let's collaborate via the discussion thread and review a proposal for branch prediction API

klingaard commented 7 months ago

From our discussion in the SIG yesterday:

danbone commented 7 months ago

Updated branch to walk the ROB when restoring the rename map table following a flush, to fix the hack I did in the previous commit, and in anticipation of adding execute redirect on branch misprediction.

On the last point, moving ROB allocation to rename isn't the only solution, and even now it requires that the ROB is updated before the flush creating a constraint on the reorder buffer write port being scheduled on the PortUpdate phase with a 1 cycle delay.

  1. I thought about keeping a similar ROB structure within rename to ensure all instructions that update the rename table are captured.
  2. Also considered using the sparta::SharedData container around the rename map and cancelling NS on flush.
  3. Or keeping two versions of the map, the current one and another updated as instructions are written to the ROB.

I'm sure there are more (better) ideas out there..

danbone commented 6 months ago

Moving forward following the discussion in our last meeting on the 20th of December. I think we should separate out the changes needed for flushing. Then rebase the branch prediction API branch on top of it and close this PR