Skip to content

Commit

Permalink
print branch misprediction statistics at the end
Browse files Browse the repository at this point in the history
  • Loading branch information
andrej committed Jan 12, 2025
1 parent 90f3daf commit 285718f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
4 changes: 3 additions & 1 deletion CustomStages/MCADFetchDelayStage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ llvm::Error MCADFetchDelayStage::execute(llvm::mca::InstRef &IR) {
(fellThrough ? AbstractBranchPredictorUnit::NOT_TAKEN
: AbstractBranchPredictorUnit::TAKEN);
BPU->recordTakenBranch(*previousInstrAddr, actualBranchDirection);


stats.numBranches.inc();
if(actualBranchDirection != predictedBranchDirection) {
// Previous prediction was wrong; this instruction will have extra
// latency due to misprediction.
delayCyclesLeft += BPU->getMispredictionPenalty();
stats.numMispredictions.inc();
LLVM_DEBUG(dbgs() << "[MCAD FetchDelayStage] Previous branch at ");
LLVM_DEBUG(dbgs().write_hex(instrAddr->addr));
LLVM_DEBUG(dbgs() << " mispredicted, delaying next instruction by "
Expand Down
24 changes: 24 additions & 0 deletions CustomStages/MCADFetchDelayStage.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class MCADFetchDelayStage : public llvm::mca::Stage {
llvm::mca::InstRef IR;
};


const llvm::MCInstrInfo &MCII;
std::deque<DelayedInstr> instrQueue = {};

Expand All @@ -48,6 +49,29 @@ class MCADFetchDelayStage : public llvm::mca::Stage {
std::optional<MDInstrAddr> previousInstrAddr = std::nullopt;
std::optional<unsigned> previousInstrSize = std::nullopt;

public:
// Stats
// TODO: Move these elsewhere, as they are useful outside of just branch
// prediction or the FetchDelayStage; we could also make use of the event
// infrastructure that already exists (grep for STALL event)
struct OverflowableCount {
unsigned long long count;
bool overflowed;
void inc() {
if(count + 1 < count) {
overflowed = true;
}
count++;
}
};

struct Statistics {
OverflowableCount numBranches = {};
OverflowableCount numMispredictions = {};
};

Statistics stats = {};

public:
MCADFetchDelayStage(const llvm::MCInstrInfo &MCII, MetadataRegistry &MD,
AbstractBranchPredictorUnit *BPU,
Expand Down
7 changes: 7 additions & 0 deletions MCAWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ std::unique_ptr<AbstractBranchPredictorUnit> buildBranchPredictor() {

} // anonymous namespace

MCADFetchDelayStage::Statistics *FetchDelayStats = nullptr; // TODO: ugly; move this elsewhere using hardware events

void BrokerFacade::setBroker(std::unique_ptr<Broker> &&B) {
Worker.TheBroker = std::move(B);
}
Expand Down Expand Up @@ -295,6 +297,7 @@ std::unique_ptr<mca::Pipeline> MCAWorker::createDefaultPipeline() {
// Create the pipeline stages.
auto Fetch = std::make_unique<EntryStage>(SrcMgr);
auto FetchDelay = std::make_unique<MCADFetchDelayStage>(MCII, MDRegistry, BPU.get(), L1I);
FetchDelayStats = &FetchDelay->stats; // TODO: ugly; move this elsewhere using hardware events
auto Dispatch = std::make_unique<DispatchStage>(STI, MRI, MCAPO.DispatchWidth,
*RCU, *PRF);
auto Execute =
Expand Down Expand Up @@ -610,6 +613,10 @@ void MCAWorker::printMCA(StringRef RegionDescription) {
<< RegionDescription << " ===\n";

MCAPipelinePrinter->printReport(OS);
if(FetchDelayStats) {
OS << "Branch Instructions: " << FetchDelayStats->numBranches.count << (FetchDelayStats->numBranches.overflowed ? " (overflowed)" : "") << "\n";
OS << "Branch Mispredictions: " << FetchDelayStats->numMispredictions.count << (FetchDelayStats->numMispredictions.overflowed ? " (overflowed)" : "") << "\n";
}
}

MCAWorker::~MCAWorker() {
Expand Down

0 comments on commit 285718f

Please sign in to comment.