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

cpu-o3: accurate port busy check #210

Merged
merged 1 commit into from
Dec 19, 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
1 change: 1 addition & 0 deletions src/cpu/o3/commit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ Commit::tick()

if (cpu->curCycle() - lastCommitCycle > 20000) {
if (maybeStucked) {
warn("[sn:%s] %s", rob->head->get()->seqNum, rob->head->get()->staticInst->disassemble(0));
panic("cpu stucked!!\n");
}
warn("cpu may be stucked\n");
Expand Down
10 changes: 4 additions & 6 deletions src/cpu/o3/dyn_inst.hh
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ class DynInst : public ExecContext, public RefCounted
protected:
enum Status
{
IqEntry, /// Instruction is in the IQ
RobEntry, /// Instruction is in the ROB
LsqEntry, /// Instruction is in the LSQ
Completed, /// Instruction has completed
Expand All @@ -166,6 +165,7 @@ class DynInst : public ExecContext, public RefCounted
MemDepSolved, /// Memory dependencies are solved
InReadyQue, /// Instruction is in the ready queue
Canceled, /// Instruction is canceled
Scheduled, /// Instruction is scheduled
ArbFailed,
Issued, /// Instruction has issued
Executed, /// Instruction has executed
Expand Down Expand Up @@ -849,8 +849,6 @@ class DynInst : public ExecContext, public RefCounted
/** Returns whether or not this instruction has issued. */
bool isIssued() const { return status[Issued]; }

/** Clears this instruction as being issued. */
void clearIssued() { status.reset(Issued); }

/** Sets this instruction as executed. */
void setExecuted() { status.set(Executed); }
Expand Down Expand Up @@ -886,13 +884,13 @@ class DynInst : public ExecContext, public RefCounted
//Instruction Queue Entry
//-----------------------
/** Sets this instruction as a entry the IQ. */
void setInIQ() { status.set(IqEntry); }
void setScheduled() { status.set(Scheduled); }

/** Sets this instruction as a entry the IQ. */
void clearInIQ() { status.reset(IqEntry); }
void clearScheduled() { status.reset(Scheduled); }

/** Returns whether or not this instruction has issued. */
bool isInIQ() const { return status[IqEntry]; }
bool isScheduled() const { return status[Scheduled]; }

/** Sets this instruction as squashed in the IQ. */
void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
Expand Down
76 changes: 45 additions & 31 deletions src/cpu/o3/issue_queue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ IssueQue::addToFu(const DynInstPtr& inst)
panic("%s [sn:%llu] has alreayd been issued\n", enums::OpClassStrings[inst->opClass()], inst->seqNum);
}
inst->setIssued();
scheduler->addToFU(inst);
POPINST(inst);
scheduler->addToFU(inst);
}

void
Expand All @@ -248,24 +248,12 @@ IssueQue::issueToFu()
if (!inst) {
continue;
}
if (portBusy[inst->issueportid]) {
DPRINTF(Schedule, "port%d busy, retry\n", inst->issueportid);
iqstats->portBusy[inst->issueportid]++;
// replay it
inst->setInReadyQ();
readyQclassify[inst->opClass()]->push(inst); // retry
continue;
}
if (!checkScoreboard(inst)) {
continue;
}
addToFu(inst);
cpu->perfCCT->updateInstPos(inst->seqNum, PerfRecord::AtIssueReadReg);
issued++;
if (!opPipelined[inst->opClass()]) [[unlikely]] {
// set fu busy
portBusy[inst->issueportid] = scheduler->getOpLatency(inst) - 1;
}
}
for (int i = size; !replayQ.empty() && i < outports; i++) {
auto inst = replayQ.front();
Expand Down Expand Up @@ -373,6 +361,21 @@ IssueQue::addIfReady(const DynInstPtr& inst)
}
}

void
IssueQue::cancel(const DynInstPtr& inst)
{
// before issued
assert(!inst->isIssued());

inst->setCancel();
if (inst->isScheduled() && !opPipelined[inst->opClass()]) {
inst->clearScheduled();
portBusy[inst->issueportid] = 0;
}

iqstats->canceledInst++;
}

void
IssueQue::selectInst()
{
Expand All @@ -389,6 +392,10 @@ IssueQue::selectInst()
}
if (!readyQ->empty()) {
auto inst = readyQ->top();
if (portBusy[pi] & (1llu << scheduler->getCorrectedOpLat(inst))) {
continue;
}

DPRINTF(Schedule, "[sn %ld] was selected\n", inst->seqNum);

// get regfile read port
Expand Down Expand Up @@ -431,9 +438,16 @@ IssueQue::scheduleInst()
} else [[likely]] {
DPRINTF(Schedule, "[sn:%llu] no conflict, scheduled\n", inst->seqNum);
iqstats->portissued[pi]++;
inst->clearInIQ();
inst->setScheduled();
toIssue->push(inst);
inst->issueportid = pi;

if (!opPipelined[inst->opClass()]) {
portBusy[pi] = -1ll;
} else if (scheduler->getCorrectedOpLat(inst) > 1) {
portBusy[pi] |= 1ll << scheduler->getCorrectedOpLat(inst);
}

scheduler->specWakeUpDependents(inst, this);
cpu->perfCCT->updateInstPos(inst->seqNum, PerfRecord::AtIssueArb);
}
Expand All @@ -451,12 +465,12 @@ IssueQue::tick()
}
instNumInsert = 0;

for (auto& t : portBusy) {
t = t > 0 ? t - 1 : t;
}

scheduleInst();
inflightIssues.advance();

for (auto& t : portBusy) {
t = t >> 1;
}
}

bool
Expand All @@ -472,8 +486,8 @@ IssueQue::ready()
bool
IssueQue::full()
{
bool full = instNumInsert + instNum >= iqsize;
full |= replayQ.size() > replayQsize; // TODO: parameterize it
bool full = instNum >= iqsize;
full |= replayQ.size() > replayQsize;
if (full) {
DPRINTF(Schedule, "has full!\n");
}
Expand All @@ -493,7 +507,6 @@ IssueQue::insert(const DynInstPtr& inst)
cpu->perfCCT->updateInstPos(inst->seqNum, PerfRecord::AtIssueQue);

DPRINTF(Schedule, "[sn:%llu] %s insert into %s\n", inst->seqNum, enums::OpClassStrings[inst->opClass()], iqname);
DPRINTF(Schedule, "[sn:%llu] instNum++\n", inst->seqNum);
inst->issueQue = this;
instList.emplace_back(inst);
bool addToDepGraph = false;
Expand Down Expand Up @@ -551,17 +564,20 @@ IssueQue::doSquash(const InstSeqNum seqNum)
{
for (auto it = instList.begin(); it != instList.end();) {
if ((*it)->seqNum > seqNum) {
(*it)->setSquashedInIQ();
(*it)->setCanCommit();
(*it)->clearInIQ();
(*it)->setCancel();
if (!(*it)->isIssued()) {
POPINST((*it));
(*it)->setIssued();
} else if ((*it)->issueportid >= 0) {
}
if ((*it)->isScheduled() && !opPipelined[(*it)->opClass()]) {
portBusy[(*it)->issueportid] = 0;
}

(*it)->setSquashedInIQ();
(*it)->setCanCommit();
(*it)->clearScheduled();
(*it)->setCancel();
it = instList.erase(it);
assert(instList.size() >= instNum);
} else {
it++;
}
Expand Down Expand Up @@ -734,6 +750,8 @@ Scheduler::addToFU(const DynInstPtr& inst)
void
Scheduler::tick()
{
// we need to update portBusy counter each cycle
cpu->activateStage(CPU::IEWIdx);
for (auto it : issueQues) {
it->tick();
}
Expand Down Expand Up @@ -821,7 +839,6 @@ Scheduler::addProducer(const DynInstPtr& inst)
void
Scheduler::insert(const DynInstPtr& inst)
{
inst->setInIQ();
auto& iqs = dispTable[inst->opClass()];
bool inserted = false;

Expand Down Expand Up @@ -853,7 +870,6 @@ Scheduler::insert(const DynInstPtr& inst)
void
Scheduler::insertNonSpec(const DynInstPtr& inst)
{
inst->setInIQ();
auto& iqs = dispTable[inst->opClass()];

for (auto iq : iqs) {
Expand Down Expand Up @@ -976,11 +992,9 @@ Scheduler::loadCancel(const DynInstPtr& inst)
int srcIdx = it.first;
auto& depInst = it.second;
if (depInst->readySrcIdx(srcIdx) && depInst->renamedSrcIdx(srcIdx) != cpu->vecOnesPhysRegId) {
assert(!depInst->isIssued());
DPRINTF(Schedule, "cancel [sn:%llu], clear src p%d ready\n", depInst->seqNum,
depInst->renamedSrcIdx(srcIdx)->flatIndex());
depInst->setCancel();
iq->iqstats->canceledInst++;
depInst->issueQue->cancel(depInst);
depInst->clearSrcRegReady(srcIdx);
dfs.push(depInst);
}
Expand Down
3 changes: 2 additions & 1 deletion src/cpu/o3/issue_queue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class IssueQue : public SimObject
// issueport : regfileport : priority
std::vector<std::vector<std::pair<int, int>>> intRfTypePortId;
std::vector<std::vector<std::pair<int, int>>> fpRfTypePortId;
std::vector<int> portBusy;
std::vector<int64_t> portBusy;
// opclass mapping to pipeid
std::vector<ReadyQue*> readyQclassify;
// s0: wakeup inst, add ready inst to readyInstsQue
Expand Down Expand Up @@ -145,6 +145,7 @@ class IssueQue : public SimObject
void selectInst();
void scheduleInst();
void addIfReady(const DynInstPtr& inst);
void cancel(const DynInstPtr& inst);

public:
inline void clearBusy(uint32_t pi) { portBusy.at(pi) = 0; }
Expand Down
Loading