Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add counters to record MMU misses and BTB misses #75

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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