diff options
author | Andreas Sandberg <andreas@sandberg.pp.se> | 2014-02-09 20:49:28 +0100 |
---|---|---|
committer | Andreas Sandberg <andreas@sandberg.pp.se> | 2014-02-09 20:49:28 +0100 |
commit | c52190a695dc1928713e5bbda85cd17867c7e465 (patch) | |
tree | 8e9e03fdd3b1cf367f4fa9e28eaf8458947cfcf7 /src/cpu/simple/base.cc | |
parent | eb73a14fe29ff4940a206a9961e30c2376412951 (diff) | |
download | gem5-c52190a695dc1928713e5bbda85cd17867c7e465.tar.xz |
cpu: simple: Add support for using branch predictors
This changesets adds branch predictor support to the
BaseSimpleCPU. The simple CPUs normally don't need a branch predictor,
however, there are at least two cases where it can be desirable:
1) A simple CPU can be used to warm the branch predictor of an O3
CPU before switching to the slower O3 model.
2) The simple CPU can be used as a quick way of evaluating/debugging
new branch predictors since it exposes branch predictor
statistics.
Limitations:
* Since the simple CPU doesn't speculate, only one instruction will
be active in the branch predictor at a time (i.e., the branch
predictor will never see speculative branches).
* The outcome of a branch prediction does not affect the performance
of the simple CPU.
Diffstat (limited to 'src/cpu/simple/base.cc')
-rw-r--r-- | src/cpu/simple/base.cc | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 078f490e8..3adf6d27f 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -60,6 +60,7 @@ #include "cpu/checker/cpu.hh" #include "cpu/checker/thread_context.hh" #include "cpu/exetrace.hh" +#include "cpu/pred/bpred_unit.hh" #include "cpu/profile.hh" #include "cpu/simple_thread.hh" #include "cpu/smt.hh" @@ -85,7 +86,9 @@ using namespace std; using namespace TheISA; BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p) - : BaseCPU(p), traceData(NULL), thread(NULL) + : BaseCPU(p), + branchPred(p->branchPred), + traceData(NULL), thread(NULL) { if (FullSystem) thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb, @@ -286,6 +289,21 @@ BaseSimpleCPU::regStats() idleFraction = constant(1.0) - notIdleFraction; numIdleCycles = idleFraction * numCycles; numBusyCycles = (notIdleFraction)*numCycles; + + numBranches + .name(name() + ".Branches") + .desc("Number of branches fetched") + .prereq(numBranches); + + numPredictedBranches + .name(name() + ".predictedBranches") + .desc("Number of branches predicted as taken") + .prereq(numPredictedBranches); + + numBranchMispred + .name(name() + ".BranchMispred") + .desc("Number of branch mispredictions") + .prereq(numBranchMispred); } void @@ -434,6 +452,19 @@ BaseSimpleCPU::preExecute() curStaticInst->getName(), curStaticInst->machInst); #endif // TRACING_ON } + + if (branchPred && curStaticInst && curStaticInst->isControl()) { + // Use a fake sequence number since we only have one + // instruction in flight at the same time. + const InstSeqNum cur_sn(0); + const ThreadID tid(0); + pred_pc = thread->pcState(); + const bool predict_taken( + branchPred->predict(curStaticInst, cur_sn, pred_pc, tid)); + + if (predict_taken) + ++numPredictedBranches; + } } void @@ -464,6 +495,10 @@ BaseSimpleCPU::postExecute() CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr()); } + if (curStaticInst->isControl()) { + ++numBranches; + } + /* Power model statistics */ //integer alu accesses if (curStaticInst->isInteger()){ @@ -507,10 +542,11 @@ BaseSimpleCPU::postExecute() } } - void BaseSimpleCPU::advancePC(Fault fault) { + const bool branching(thread->pcState().branching()); + //Since we're moving to a new pc, zero out the offset fetchOffset = 0; if (fault != NoFault) { @@ -526,6 +562,23 @@ BaseSimpleCPU::advancePC(Fault fault) thread->pcState(pcState); } } + + if (branchPred && curStaticInst && curStaticInst->isControl()) { + // Use a fake sequence number since we only have one + // instruction in flight at the same time. + const InstSeqNum cur_sn(0); + const ThreadID tid(0); + + if (pred_pc == thread->pcState()) { + // Correctly predicted branch + branchPred->update(cur_sn, tid); + } else { + // Mis-predicted branch + branchPred->squash(cur_sn, pcState(), + branching, tid); + ++numBranchMispred; + } + } } void |