Skip to content

Commit

Permalink
add capacity limit and LRU policy for naive branch predictor
Browse files Browse the repository at this point in the history
  • Loading branch information
andrej committed Dec 1, 2024
1 parent 50cd673 commit ed90e9b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
23 changes: 21 additions & 2 deletions CustomHWUnits/NaiveBranchPredictorUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,31 @@ namespace llvm {
namespace mcad {

void NaiveBranchPredictorUnit::recordTakenBranch(MDInstrAddr instrAddr, BranchDirection nextInstrDirection) {
branchHistory[instrAddr] = nextInstrDirection;
// If no entry exists yet, add one
if(branchHistory.find(instrAddr) == branchHistory.end()) {
branchHistory[instrAddr] = {};
}
// Update the entry
branchHistory[instrAddr].lastDirection = nextInstrDirection;
branchHistory[instrAddr].lastUse = nAccesses;

// Evict the least recently used entry if we are at capacity
if(branchHistory.size() >= historyCapacity) {
auto min_it = branchHistory.begin();
for(auto it = branchHistory.begin(); it != branchHistory.end(); it++) {
if(it->second.lastUse < min_it->second.lastUse) {
min_it = it;
}
}
branchHistory.erase(min_it);
}
}

AbstractBranchPredictorUnit::BranchDirection NaiveBranchPredictorUnit::predictBranch(MDInstrAddr instrAddr) {
++nAccesses;
if(branchHistory.find(instrAddr) != branchHistory.end()) {
return branchHistory[instrAddr];
branchHistory[instrAddr].lastUse = nAccesses;
return branchHistory[instrAddr].lastDirection;
}
// We have no history on this; predict a fall-through branch
return NOT_TAKEN;
Expand Down
14 changes: 12 additions & 2 deletions CustomHWUnits/NaiveBranchPredictorUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@ namespace llvm {
namespace mcad {

class NaiveBranchPredictorUnit : public AbstractBranchPredictorUnit {

struct HistoryEntry {
AbstractBranchPredictorUnit::BranchDirection lastDirection;
unsigned lastUse;
};

unsigned mispredictionPenalty;
std::map<MDInstrAddr, AbstractBranchPredictorUnit::BranchDirection> branchHistory = {};
unsigned historyCapacity;
unsigned nAccesses;
std::map<MDInstrAddr, struct HistoryEntry> branchHistory = {};

public:
NaiveBranchPredictorUnit(unsigned mispredictionPenalty = 20) : mispredictionPenalty(mispredictionPenalty) {};
NaiveBranchPredictorUnit(unsigned mispredictionPenalty, unsigned branchHistoryTableSize)
: mispredictionPenalty(mispredictionPenalty),
historyCapacity(branchHistoryTableSize) { };

void recordTakenBranch(MDInstrAddr instrAddr, BranchDirection nextInstrDirection) override;

Expand Down
9 changes: 7 additions & 2 deletions MCAWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ static cl::opt<unsigned>
cl::desc("Delay (# cycles) added to the fetch stage of the next instruction after a branch misprediction"),
cl::init(20U));

static cl::opt<unsigned>
BranchHistoryTableSize("bht-size",
cl::desc("Size of the simulated branch history table for branch prediction"),
cl::init(10U));

void BrokerFacade::setBroker(std::unique_ptr<Broker> &&B) {
Worker.TheBroker = std::move(B);
}
Expand Down Expand Up @@ -187,7 +192,7 @@ std::unique_ptr<mca::Pipeline> MCAWorker::createDefaultPipeline() {
MCAPO.StoreQueueSize,
MCAPO.AssumeNoAlias, &MDRegistry);
auto HWS = std::make_unique<Scheduler>(SM, *LSU);
auto BPU = std::make_unique<NaiveBranchPredictorUnit>(BranchMispredictionDelay);
auto BPU = std::make_unique<NaiveBranchPredictorUnit>(BranchMispredictionDelay, BranchHistoryTableSize);

// Create the pipeline stages.
auto Fetch = std::make_unique<EntryStage>(SrcMgr);
Expand Down Expand Up @@ -232,7 +237,7 @@ std::unique_ptr<mca::Pipeline> MCAWorker::createInOrderPipeline() {
auto LSU = std::make_unique<MCADLSUnit>(SM, MCAPO.LoadQueueSize,
MCAPO.StoreQueueSize,
MCAPO.AssumeNoAlias, &MDRegistry);
auto BPU = std::make_unique<NaiveBranchPredictorUnit>(20);
auto BPU = std::make_unique<NaiveBranchPredictorUnit>(BranchMispredictionDelay, BranchHistoryTableSize);

// Create the pipeline stages.
auto Entry = std::make_unique<EntryStage>(SrcMgr);
Expand Down

0 comments on commit ed90e9b

Please sign in to comment.