Skip to content

Commit

Permalink
feat: Add counters to record MMU misses and BTB misses
Browse files Browse the repository at this point in the history
  • Loading branch information
xusine committed Oct 16, 2024
1 parent bd44105 commit 155e8c3
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 6 deletions.
46 changes: 42 additions & 4 deletions components/BranchPredictor/BranchPredictor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ BranchPredictor::BranchPredictor(std::string const& aName, uint32_t anIndex, uin
, theSerial(0)
, theBTB(aBTBSets, aBTBWays)
, theBranches(aName + "-branches")

, thePredictions_TAGE(aName + "-predictions:TAGE")
, theCorrect_TAGE(aName + "-correct:TAGE")
, theMispredict_TAGE(aName + "-mispredict:TAGE")

, thePredictions_BTB(aName + "-predictions:BTB")
, theCorrect_BTB(aName + "-correct:BTB")
, theMispredict_BTB(aName + "-mispredict:BTB")
{
}

Expand All @@ -32,11 +37,16 @@ BranchPredictor::BranchPredictor(std::string const& aName, uint32_t anIndex, uin
VirtualMemoryAddress
BranchPredictor::predictConditional(VirtualMemoryAddress anAddress, BPredState& aBPState)
{
++thePredictions_TAGE;

bool isTaken = theTage.get_prediction((uint64_t)anAddress, aBPState);

aBPState.thePrediction = isTaken ? kTaken : kNotTaken;

if (aBPState.thePrediction <= kTaken && theBTB.target(anAddress)) { return *theBTB.target(anAddress); }
if (aBPState.thePrediction <= kTaken && theBTB.target(anAddress)) {
++thePredictions_BTB;
return *theBTB.target(anAddress);
}

return VirtualMemoryAddress(0);
}
Expand Down Expand Up @@ -70,7 +80,6 @@ BranchPredictor::isBranch(VirtualMemoryAddress anAddress)
VirtualMemoryAddress
BranchPredictor::predict(VirtualMemoryAddress anAddress, BPredState& aBPState)
{
++thePredictions_TAGE;
// Implementation of predict function
aBPState.pc = anAddress;
aBPState.thePredictedType = theBTB.type(anAddress);
Expand Down Expand Up @@ -143,10 +152,39 @@ BranchPredictor::feedback(VirtualMemoryAddress anAddress,
aBPState.theActualType = anActualType;

if (is_mispredict) {
++theMispredict_TAGE;

if (aBPState.thePredictedType == kConditional) {
// we need to figure out whether the direction was correct or the target was correct
if (aBPState.thePrediction <= kTaken) {
if (anActualDirection >= kTaken) {
++theMispredict_TAGE;
} else {
++theMispredict_BTB;
}
} else {
if (anActualAddress != aBPState.thePredictedTarget) {
++theMispredict_BTB;
} else {
++theMispredict_TAGE;
}
}
} else {
++theMispredict_BTB;
}

reconstructHistory(aBPState);
} else {
++theCorrect_TAGE;
// If the prediction was correct, we need to update the stats
if (aBPState.thePredictedType == kConditional) {
if (aBPState.thePrediction <= kTaken) {
++theCorrect_TAGE;
} else {
++theCorrect_BTB;
++theCorrect_TAGE;
}
} else {
++theCorrect_BTB;
}
}
++theBranches;

Expand Down
5 changes: 5 additions & 0 deletions components/BranchPredictor/BranchPredictor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ class BranchPredictor

public:
Stat::StatCounter theBranches;

Stat::StatCounter thePredictions_TAGE;
Stat::StatCounter theCorrect_TAGE;
Stat::StatCounter theMispredict_TAGE;

Stat::StatCounter thePredictions_BTB;
Stat::StatCounter theCorrect_BTB;
Stat::StatCounter theMispredict_BTB;

private:
/* Depending on whether the prediction of the Branch Predictor we use is Taken or Not Taken, the target is returned
* If the prediction is NotTaken, there is no need to read the BTB as we will anyway jump to the next instruction
Expand Down
32 changes: 30 additions & 2 deletions components/MMU/MMUImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include FLEXUS_BEGIN_COMPONENT_IMPLEMENTATION()

#include <core/checkpoint/json.hpp>
#include <core/stats.hpp>

using json = nlohmann::json;

Expand Down Expand Up @@ -95,7 +96,10 @@ class FLEXUS_COMPONENT(MMU)

theTLB.clear();

if (size != theSize) { resize(size); }
if (size != theSize) {
DBG_Assert(false, (<< "TLB size mismatch: " << size << " != " << theSize));
}
resize(size);

size_t TLBSize = checkpoint["entries"].size();
for (size_t i = 0; i < TLBSize; i++) {
Expand Down Expand Up @@ -203,6 +207,12 @@ class FLEXUS_COMPONENT(MMU)
Flexus::Qemu::Processor theCPU;
std::shared_ptr<mmu_t> theMMU;


Stat::StatCounter itlb_accesses;
Stat::StatCounter dtlb_accesses;
Stat::StatCounter itlb_misses;
Stat::StatCounter dtlb_misses;

// Is true when the MMU has been reseted
bool mmu_is_init;

Expand All @@ -225,7 +235,9 @@ class FLEXUS_COMPONENT(MMU)

public:
FLEXUS_COMPONENT_CONSTRUCTOR(MMU)
: base(FLEXUS_PASS_CONSTRUCTOR_ARGS)
: base(FLEXUS_PASS_CONSTRUCTOR_ARGS), itlb_accesses(statName() + "-itlb_accesses"),
dtlb_accesses(statName() + "-dtlb_accesses"), itlb_misses(statName() + "-itlb_misses"),
dtlb_misses(statName() + "-dtlb_misses")
{
}

Expand Down Expand Up @@ -322,6 +334,14 @@ class FLEXUS_COMPONENT(MMU)
entry.second = perfectPaddr;
if (perfectPaddr == 0xFFFFFFFFFFFFFFFF) item->setPagefault();
}

if (item->isInstr() && entry.first) {
itlb_accesses++;
} else if (entry.first) {
dtlb_accesses++;
}


if (entry.first) {
DBG_(VVerb, (<< "Item is a Hit " << item->theVaddr));

Expand All @@ -336,6 +356,14 @@ class FLEXUS_COMPONENT(MMU)
} else {
DBG_(VVerb, (<< "Item is a miss " << item->theVaddr));


if (item->isInstr()) {
itlb_misses++;
} else {
dtlb_misses++;
}


VirtualMemoryAddress pageAddr(item->theVaddr & PAGEMASK);
if (alreadyPW.find(pageAddr) == alreadyPW.end()) {
// mark miss
Expand Down

0 comments on commit 155e8c3

Please sign in to comment.