Skip to content

Commit

Permalink
cpu-o3: implement compress rob
Browse files Browse the repository at this point in the history
Change-Id: I0c41f3c0b8e5128c3b07dc81a5c27f5fb9cf0677
  • Loading branch information
tastynoob committed Feb 24, 2025
1 parent 7210df6 commit 9714711
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 47 deletions.
8 changes: 4 additions & 4 deletions src/cpu/o3/BaseO3CPU.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,6 @@ def support_take_over(cls):
EnableLdMissReplay = Param.Bool(True, "Replay Cache missed load instrution from ReplayQ if True")
EnablePipeNukeCheck = Param.Bool(True, "Replay load if Raw violation is detected in loadPipe if True")


numRobs = Param.Unsigned(1, "Number of Reorder Buffers");

numPhysIntRegs = Param.Unsigned(224,
"Number of physical integer registers")
numPhysFloatRegs = Param.Unsigned(192, "Number of physical floating point "
Expand All @@ -212,7 +209,10 @@ def support_take_over(cls):
numPhysCCRegs = Param.Unsigned(0, "Number of physical cc registers")
numPhysRMiscRegs = Param.Unsigned(40, "Number of physical renameable misc registers")

numROBEntries = Param.Unsigned(320, "Number of reorder buffer entries")
# rob config
numRobs = Param.Unsigned(1, "Number of Reorder Buffers");
numROBEntries = Param.Unsigned(160, "Number of reorder buffer entries")
CROB_instPerGroup = Param.Unsigned(8, "Number of reorder buffer entries")

smtNumFetchingThreads = Param.Unsigned(1, "SMT Number of Fetching Threads")
smtFetchPolicy = Param.SMTFetchPolicy('RoundRobin', "SMT Fetch policy")
Expand Down
20 changes: 3 additions & 17 deletions src/cpu/o3/commit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ Commit::CommitStats::CommitStats(CPU *cpu, Commit *commit)
branchMispredicts.prereq(branchMispredicts);

numCommittedDist
.init(0,commit->commitWidth,1)
.flags(statistics::pdf);
.init(0,commit->commitWidth * 8,1)
.flags(statistics::pdf).flags(statistics::nozero);

segUnitStrideNF
.init(0, 8, 1)
Expand Down Expand Up @@ -1107,21 +1107,7 @@ Commit::commitInsts()

DynInstPtr head_inst;

int commit_width = commitWidth;
int count_ = 0;
ThreadID tid = getCommittingThread();
if (tid > -1) {
for (auto& it : *(rob->getInstList(tid))) {
count_++;
if (it->opClass() == FMAAccOp) {
commit_width++;
}
if (count_ >= commitWidth ||
commit_width >= commitWidth * 2) {
break;
}
}
}
int commit_width = rob->numInstCanCommit(commitWidth);

// Commit as many instructions as possible until the commit bandwidth
// limit is reached, or it becomes impossible to commit any more.
Expand Down
86 changes: 69 additions & 17 deletions src/cpu/o3/rob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ ROB::ROB(CPU *_cpu, const BaseO3CPUParams &params)
robWalkPolicy(params.robWalkPolicy),
cpu(_cpu),
numEntries(params.numROBEntries),
instsPerGroup(params.CROB_instPerGroup),
rollbackWidth(params.squashWidth),
replayWidth(params.replayWidth),
constSquashCycle(params.ConstSquashCycle),
Expand Down Expand Up @@ -114,7 +115,7 @@ void
ROB::resetState()
{
for (ThreadID tid = 0; tid < MaxThreads; tid++) {
threadEntries[tid] = 0;
threadGroups[tid].clear();
squashIt[tid] = instList[tid].end();
squashedSeqNum[tid] = 0;
doneSquashing[tid] = true;
Expand Down Expand Up @@ -203,6 +204,19 @@ ROB::countInsts(ThreadID tid)
return instList[tid].size();
}

uint32_t
ROB::numInstCanCommit(int groups)
{
int sum = 0;
for (ThreadID tid = 0; tid < numThreads; tid++) {
auto it = threadGroups[tid].begin();
for (int i = 0; i < groups && it != threadGroups[tid].end(); i++, it++) {
sum += (*it == crob_magic_num) ? 1 : *it;
}
}
return sum;
}

void
ROB::insertInst(const DynInstPtr &inst)
{
Expand All @@ -212,7 +226,7 @@ ROB::insertInst(const DynInstPtr &inst)

DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState());

assert(numInstsInROB != numEntries);
assert(numInstsInROB <= numEntries * instsPerGroup);

ThreadID tid = inst->threadNumber;

Expand All @@ -232,12 +246,30 @@ ROB::insertInst(const DynInstPtr &inst)
inst->setInROB();

++numInstsInROB;
++threadEntries[tid];
// allocate group
if (inst->isMemRef() || inst->isControl() || inst->isNonSpeculative()) {
if (!threadGroups[tid].empty()) {
auto t = threadGroups[tid].back() == crob_magic_num ? 1 : threadGroups[tid].back();
stats.instPergroup.sample(t);
}

// exclusive one entry
threadGroups[tid].push_back(crob_magic_num);
} else if (!threadGroups[tid].empty() && threadGroups[tid].back() < instsPerGroup) {
threadGroups[tid].back()++;
} else {

if (!threadGroups[tid].empty()) {
auto t = threadGroups[tid].back() == crob_magic_num ? 1 : threadGroups[tid].back();
stats.instPergroup.sample(t);
}
threadGroups[tid].push_back(1);
}

assert((*tail) == inst);

DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid,
threadEntries[tid]);
threadGroups[tid].size());
}

void
Expand All @@ -261,7 +293,18 @@ ROB::retireHead(ThreadID tid)
head_inst->seqNum);

--numInstsInROB;
--threadEntries[tid];

//Update Group Size
if (head_inst->isMemRef() || head_inst->isControl() ||
head_inst->isNonSpeculative()) {
// exclusive one entry
assert(threadGroups[tid].front() == crob_magic_num);
threadGroups[tid].pop_front();
} else if (threadGroups[tid].front() > 1) {
threadGroups[tid].front()--;
} else {
threadGroups[tid].pop_front();
}

head_inst->clearInROB();
head_inst->setCommitted();
Expand All @@ -279,7 +322,8 @@ bool
ROB::isHeadReady(ThreadID tid)
{
stats.reads++;
if (threadEntries[tid] != 0) {

if (!threadGroups[tid].empty() && threadGroups[tid].front() != 0) {
return instList[tid].front()->readyToCommit();
}

Expand All @@ -304,16 +348,10 @@ ROB::canCommit()
return false;
}

unsigned
ROB::numFreeEntries()
{
return numEntries - numInstsInROB;
}

unsigned
ROB::numFreeEntries(ThreadID tid)
{
return maxEntries[tid] - threadEntries[tid];
return maxEntries[tid] - threadGroups[tid].size();
}

void
Expand Down Expand Up @@ -345,7 +383,7 @@ ROB::doSquash(ThreadID tid)
// Set the number to the number of entries (the max).
if (cpu->isThreadExiting(tid))
{
num_insts_to_squash = numEntries;
num_insts_to_squash = numEntries * instsPerGroup;
}

for (int numSquashed = 0;
Expand All @@ -369,7 +407,18 @@ ROB::doSquash(ThreadID tid)

auto prevIt = std::prev(squashIt[tid]);
--numInstsInROB;
--threadEntries[tid];

//Update Group Size
if ((*squashIt[tid])->isMemRef() || (*squashIt[tid])->isControl() ||
(*squashIt[tid])->isNonSpeculative()) {
// exclusive one entry
assert(threadGroups[tid].back() == crob_magic_num);
threadGroups[tid].pop_back();
} else if (threadGroups[tid].back() > 1) {
threadGroups[tid].back()--;
} else {
threadGroups[tid].pop_back();
}

(*squashIt[tid])->clearInROB();
// head_inst->setCommitted();
Expand Down Expand Up @@ -572,7 +621,8 @@ ROB::computeDynSquashWidth(unsigned uncommitted_insts, unsigned to_squash)
const DynInstPtr&
ROB::readHeadInst(ThreadID tid)
{
if (threadEntries[tid] != 0) {
if (!threadGroups[tid].empty() && threadGroups[tid].front() != 0) {
assert(instList[tid].size() > 0);
InstIt head_thread = instList[tid].begin();

assert((*head_thread)->isInROB());
Expand All @@ -597,8 +647,10 @@ ROB::ROBStats::ROBStats(statistics::Group *parent)
ADD_STAT(reads, statistics::units::Count::get(),
"The number of ROB reads"),
ADD_STAT(writes, statistics::units::Count::get(),
"The number of ROB writes")
"The number of ROB writes"),
ADD_STAT(instPergroup, statistics::units::Count::get())
{
instPergroup.init(0, 8, 1);
}

DynInstPtr
Expand Down
37 changes: 28 additions & 9 deletions src/cpu/o3/rob.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#ifndef __CPU_O3_ROB_HH__
#define __CPU_O3_ROB_HH__

#include <queue>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -172,9 +173,6 @@ class ROB
/** Number of entries needed For 'num_threads' amount of threads. */
int entryAmount(ThreadID num_threads);

/** Returns the number of total free entries in the ROB. */
unsigned numFreeEntries();

/** Returns the number of free entries in a specific ROB paritition. */
unsigned numFreeEntries(ThreadID tid);

Expand All @@ -184,23 +182,28 @@ class ROB

/** Returns the number of entries being used by a specific thread. */
unsigned getThreadEntries(ThreadID tid)
{ return threadEntries[tid]; }
{ return threadGroups[tid].size(); }

/** Returns if the ROB is full. */
bool isFull()
{ return numInstsInROB == numEntries; }
{
for (int i =0;i<MaxThreads;i++) {
if (isFull(i)) return true;
}
return false;
}

/** Returns if a specific thread's partition is full. */
bool isFull(ThreadID tid)
{ return threadEntries[tid] == numEntries; }
{ return threadGroups[tid].size() == numEntries; }

/** Returns if the ROB is empty. */
bool isEmpty() const
{ return numInstsInROB == 0; }

/** Returns if a specific thread's partition is empty. */
bool isEmpty(ThreadID tid) const
{ return threadEntries[tid] == 0; }
{ return threadGroups[tid].size() == 0; }

/** Executes the squash, marking squashed instructions. */
void doSquash(ThreadID tid);
Expand Down Expand Up @@ -270,6 +273,17 @@ class ROB
*/
size_t countInsts(ThreadID tid);

uint32_t countGroupAllInst(ThreadID tid) {
int sum = 0;
for (auto it : threadGroups[tid]) {
assert(it);
sum += (it == crob_magic_num) ? 1 : it;
}
return sum;
}

uint32_t numInstCanCommit(int groups);

private:
/** Reset the ROB state */
void resetState();
Expand All @@ -283,8 +297,11 @@ class ROB
/** Number of instructions in the ROB. */
unsigned numEntries;

/** Entries Per Thread */
unsigned threadEntries[MaxThreads];
const int crob_magic_num = 0xffff;

unsigned instsPerGroup;

std::deque<unsigned> threadGroups[MaxThreads];

/** Max Insts a Thread Can Have in the ROB */
unsigned maxEntries[MaxThreads];
Expand Down Expand Up @@ -353,6 +370,8 @@ class ROB
statistics::Scalar reads;
// The number of rob_writes
statistics::Scalar writes;

statistics::Distribution instPergroup;
} stats;
};

Expand Down

0 comments on commit 9714711

Please sign in to comment.