Skip to content

Commit 33b75e7

Browse files
committed
cpu-o3: using reverse ordered tick & refactor the stalls logic
Change-Id: Id60cffa77c28f7491c095dca5ff037fdc4542675
1 parent 7542d58 commit 33b75e7

23 files changed

+804
-2351
lines changed

src/cpu/o3/comm.hh

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -219,29 +219,17 @@ struct TimeStruct
219219
StallReason blockReason;
220220
};
221221

222-
DecodeComm decodeInfo[MaxThreads];
222+
DecodeComm decodeInfo[MaxThreads]; // decode to fetch
223223

224224
struct RenameComm
225225
{
226226
StallReason blockReason;
227227
};
228228

229-
RenameComm renameInfo[MaxThreads];
229+
RenameComm renameInfo[MaxThreads]; // rename to decode
230230

231231
struct IewComm
232232
{
233-
// Also eventually include skid buffer space.
234-
unsigned freeLQEntries;
235-
unsigned freeSQEntries;
236-
unsigned dispatchedToLQ;
237-
unsigned dispatchedToSQ;
238-
239-
unsigned ldstqCount;
240-
241-
unsigned dispatched;
242-
bool usedIQ;
243-
bool usedLSQ;
244-
245233
StallReason robHeadStallReason;
246234
StallReason blockReason;
247235
StallReason lqHeadStallReason;
@@ -256,7 +244,7 @@ struct TimeStruct
256244
std::vector<ResolvedCFIEntry> resolvedCFIs; // *F
257245
};
258246

259-
IewComm iewInfo[MaxThreads];
247+
IewComm iewInfo[MaxThreads]; // iew to rename, fetch
260248

261249
struct CommitComm
262250
{
@@ -300,13 +288,12 @@ struct TimeStruct
300288

301289
InstSeqNum doneMemSeqNum;
302290

291+
InstSeqNum robheadNotReadySeqNum;
292+
303293
uint64_t doneFtqId; // F
304294
uint64_t squashedTargetId; // F
305295
unsigned squashedLoopIter; // F
306296

307-
/// Tell Rename how many free entries it has in the ROB
308-
unsigned freeROBEntries; // *R
309-
310297
bool isTrapSquash;
311298
bool squash; // *F, D, R, I
312299
bool robSquashing; // *F, D, R, I
@@ -336,16 +323,20 @@ struct TimeStruct
336323

337324
};
338325

339-
CommitComm commitInfo[MaxThreads];
326+
CommitComm commitInfo[MaxThreads];// commit to iew, rename, fetch
327+
};
328+
340329

341-
bool decodeBlock[MaxThreads];
342-
bool decodeUnblock[MaxThreads];
343-
bool renameBlock[MaxThreads];
344-
bool renameUnblock[MaxThreads];
345-
bool iewBlock[MaxThreads];
346-
bool iewUnblock[MaxThreads];
330+
struct StallSignals
331+
{
332+
333+
bool blockFetch[MaxThreads];// decode to fetch
334+
bool blockDecode[MaxThreads];// rename to decode
335+
bool blockRename[MaxThreads];// iew to rename (if iew is stalling, rename all threads would be stalled)
336+
bool blockIEW[MaxThreads];// commit to iew
347337
};
348338

339+
349340
} // namespace o3
350341
} // namespace gem5
351342

src/cpu/o3/commit.cc

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Commit::Commit(CPU *_cpu, branch_prediction::BPredUnit *_bp, const BaseO3CPUPara
129129
"--debug-start=%llu --debug-end=%llu\n",
130130
lastCommitCycle, cpu->curCycle(),
131131
cpu->cyclesToTicks(Cycles(lastCommitCycle - 200)),
132-
cpu->cyclesToTicks(Cycles(lastCommitCycle + 50)));
132+
cpu->cyclesToTicks(Cycles(lastCommitCycle + 200)));
133133
}
134134
cpu->schedule(this->stuckCheckEvent, cpu->clockEdge(Cycles(40010)));
135135
}, "CommitStuckCheckEvent"),
@@ -165,7 +165,9 @@ Commit::Commit(CPU *_cpu, branch_prediction::BPredUnit *_bp, const BaseO3CPUPara
165165
}
166166
}
167167

168-
for (ThreadID tid = 0; tid < MaxThreads; tid++) {
168+
assert(renameToROBDelay == 1);
169+
170+
for (ThreadID tid = 0; tid < numThreads; tid++) {
169171
commitStatus[tid] = Idle;
170172
changedROBNumEntries[tid] = false;
171173
trapSquash[tid] = false;
@@ -181,6 +183,7 @@ Commit::Commit(CPU *_cpu, branch_prediction::BPredUnit *_bp, const BaseO3CPUPara
181183
htmStarts[tid] = 0;
182184
htmStops[tid] = 0;
183185
traceCommitIndex[tid] = 0;
186+
fixedbuffer[tid] = boost::circular_buffer<DynInstPtr>(renameWidth);
184187
}
185188
interrupt = NoFault;
186189

@@ -461,7 +464,6 @@ Commit::startupStage()
461464
// Broadcast the number of free entries.
462465
for (ThreadID tid = 0; tid < numThreads; tid++) {
463466
toIEW->commitInfo[tid].usedROB = true;
464-
toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
465467
toIEW->commitInfo[tid].emptyROB = true;
466468
}
467469

@@ -1104,10 +1106,10 @@ Commit::commit()
11041106
_nextStatus = Active;
11051107
}
11061108

1107-
if (num_squashing_threads != numThreads) {
1108-
// If we're not currently squashing, then get instructions.
1109-
getInsts();
1109+
// If we're not currently squashing, then get instructions.
1110+
moveInstsToBuffer();
11101111

1112+
if (num_squashing_threads != numThreads) {
11111113
// Try to commit any instructions.
11121114
commitInsts();
11131115
}
@@ -1120,7 +1122,6 @@ Commit::commit()
11201122

11211123
if (changedROBNumEntries[tid]) {
11221124
toIEW->commitInfo[tid].usedROB = true;
1123-
toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
11241125

11251126
wroteToTimeBuffer = true;
11261127
changedROBNumEntries[tid] = false;
@@ -1142,7 +1143,6 @@ Commit::commit()
11421143
checkEmptyROB[tid] = false;
11431144
toIEW->commitInfo[tid].usedROB = true;
11441145
toIEW->commitInfo[tid].emptyROB = true;
1145-
toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
11461146
wroteToTimeBuffer = true;
11471147
}
11481148

@@ -1242,7 +1242,9 @@ Commit::commitInsts()
12421242
if (commit_success) {
12431243
cpu->perfCCT->updateInstPos(head_inst->seqNum, PerfRecord::AtCommit);
12441244
cpu->perfCCT->commitMeta(head_inst->seqNum);
1245-
head_inst->printDisassemblyAndResult(cpu->name());
1245+
1246+
DPRINTF(CommitTrace, "CT: %s\n", head_inst->genDisassembly());
1247+
12461248
if (ismispred) {
12471249
ismispred = false;
12481250
stats.recovery_bubble += (cpu->curCycle() - lastCommitCycle) * renameWidth;
@@ -1382,7 +1384,11 @@ Commit::commitInsts()
13821384
if (head_inst->isLoad()) {
13831385
Addr load_pc = head_inst->pcState().instAddr();
13841386
Addr load_addr = head_inst->physEffAddr;
1385-
Addr load_value = head_inst->memData ? *((uint64_t *)head_inst->memData) : 0;
1387+
char buffer[8] = {0};
1388+
if (head_inst->memData) {
1389+
std::memcpy(buffer, head_inst->memData, head_inst->effSize);
1390+
}
1391+
Addr load_value = *((uint64_t *)buffer);
13861392
bool hit = loadTripleCounter.update(load_pc, load_addr, load_value);
13871393
if (hit) {
13881394
// same PC && same addr && same value
@@ -1492,6 +1498,7 @@ Commit::commitInsts()
14921498
for (int tid = 0; tid < MaxThreads; tid++) {
14931499
toIEW->commitInfo[tid].doneMemSeqNum =
14941500
std::max(toIEW->commitInfo[tid].doneSeqNum, rob->getHeadGroupLastDoneSeq(tid));
1501+
toIEW->commitInfo[tid].robheadNotReadySeqNum = rob->getHeadGroupLastNotReadySeq(tid);
14951502
}
14961503

14971504
DPRINTF(CommitRate, "%i\n", num_committed);
@@ -1806,16 +1813,54 @@ Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
18061813
}
18071814

18081815
void
1809-
Commit::getInsts()
1816+
Commit::moveInstsToBuffer()
18101817
{
18111818
DPRINTF(Commit, "Getting instructions from Rename stage.\n");
1819+
int insts_from_rename = fromRename->size;
1820+
if (insts_from_rename != 0) {
1821+
// move to buffer
1822+
ThreadID tid = fromRename->insts[0]->threadNumber;
1823+
assert(fixedbuffer[tid].empty());
1824+
for (int i = 0; i < insts_from_rename; ++i) {
1825+
const DynInstPtr &inst = fromRename->insts[i];
1826+
assert(inst->threadNumber == tid);
1827+
if (localSquashVer.largerThan(inst->getVersion())) {
1828+
inst->setSquashed();
1829+
}
1830+
fixedbuffer[tid].push_back(inst);
1831+
}
1832+
}
18121833

1813-
// Read any renamed instructions and place them into the ROB.
1814-
int insts_to_process = std::min((int)renameWidth, fromRename->size);
1834+
// check threads stall & status
1835+
ThreadID tid = InvalidThreadID;
1836+
for (int i = 0; i < numThreads; i++) {
1837+
bool robblock = commitStatus[i] == ROBSquashing || commitStatus[i] == TrapPending;
1838+
bool block = (rob->getMaxEntries(i) - rob->getThreadEntries(i) < fixedbuffer[i].size()) || robblock;
1839+
bool active = !block && !fixedbuffer[i].empty();
1840+
DPRINTF(Commit, "Thread %i: block %i robblock %i active %i\n", i, block, robblock, active);
1841+
1842+
stallSig->blockIEW[i] = block;
1843+
if (active) {
1844+
if (tid == InvalidThreadID) tid = i;
1845+
else {
1846+
// if there are multiple active threads, must exhaust all threads first
1847+
// to avoid starvation of other threads and also avoid resource conflict
1848+
stallSig->blockIEW[tid] = true;
1849+
stallSig->blockIEW[i] = true;
1850+
DPRINTF(IEW, "Multiple active threads detected, blocking all threads\n");
1851+
}
1852+
}
1853+
}
1854+
if (tid == InvalidThreadID) {
1855+
DPRINTF(Commit, "No instructions from Rename stage.\n");
1856+
return;
1857+
}
18151858

1859+
// Read any renamed instructions and place them into the ROB.
1860+
int insts_to_process = fixedbuffer[tid].size();
18161861
for (int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
1817-
const DynInstPtr &inst = fromRename->insts[inst_num];
1818-
ThreadID tid = inst->threadNumber;
1862+
const DynInstPtr &inst = fixedbuffer[tid].front();
1863+
fixedbuffer[tid].pop_front();
18191864

18201865
if (localSquashVer.largerThan(inst->getVersion())) {
18211866
inst->setSquashed();
@@ -1840,6 +1885,11 @@ Commit::getInsts()
18401885
tid, inst->seqNum, inst->pcState());
18411886
}
18421887
}
1888+
1889+
if (!fixedbuffer[tid].empty()) {
1890+
stallSig->blockIEW[tid] = true;
1891+
DPRINTF(Commit, "Not all instructions from Rename stage could be processed, blocking thread %i\n", tid);
1892+
}
18431893
}
18441894

18451895

@@ -1873,14 +1923,18 @@ Commit::markCompletedInsts()
18731923
for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
18741924
assert(fromIEW->insts[inst_num]);
18751925
if (!fromIEW->insts[inst_num]->isSquashed()) {
1876-
DPRINTF(Commit, "[tid:%i] Marking PC %s, [sn:%llu] ready "
1926+
DPRINTF(Commit,
1927+
"[tid:%i] Marking PC %s, [sn:%llu] ready "
18771928
"within ROB.\n",
1878-
fromIEW->insts[inst_num]->threadNumber,
1879-
fromIEW->insts[inst_num]->pcState(),
1929+
fromIEW->insts[inst_num]->threadNumber, fromIEW->insts[inst_num]->pcState(),
18801930
fromIEW->insts[inst_num]->seqNum);
18811931

18821932
// Mark the instruction as ready to commit.
18831933
fromIEW->insts[inst_num]->setCanCommit();
1934+
auto &inst = fromIEW->insts[inst_num];
1935+
1936+
panic_if(!rob->findInst(0, inst->seqNum), "[sn:%llu] Committed instruction not found in ROB",
1937+
inst->seqNum);
18841938
}
18851939
}
18861940
}
@@ -1901,10 +1955,7 @@ Commit::updateComInstStats(const DynInstPtr &inst)
19011955
cpu->instDone(tid, inst);
19021956
}
19031957

1904-
//
19051958
// Control Instructions
1906-
//
1907-
//
19081959
if (inst->isControl()) {
19091960
bool mispred = inst->mispredicted();
19101961
std::unique_ptr<PCStateBase> tmp_next_pc(inst->pcState().clone());

src/cpu/o3/commit.hh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private:
144144
uint64_t totalCount = 0;
145145
};
146146

147-
class Commit
147+
class Commit
148148
{
149149
public:
150150
/** Overall commit status. Used to determine if the CPU can deschedule
@@ -176,6 +176,10 @@ private:
176176
/** Per-thread status. */
177177
ThreadStatus commitStatus[MaxThreads];
178178

179+
boost::circular_buffer<DynInstPtr> fixedbuffer[MaxThreads];
180+
181+
StallSignals* stallSig;
182+
179183
bool robSquashHolding{false};
180184
/** Commit policy used in SMT mode. */
181185
CommitPolicy commitPolicy;
@@ -234,6 +238,8 @@ private:
234238

235239
void setDecodeStage(Decode *decode_stage);
236240

241+
void setStallSignals(StallSignals* stall_signals) { stallSig = stall_signals; }
242+
237243
/** The pointer to the IEW stage. Used solely to ensure that
238244
* various events (traps, interrupts, syscalls) do not occur until
239245
* all stores have written back.
@@ -373,7 +379,7 @@ private:
373379
bool commitHead(const DynInstPtr &head_inst, unsigned inst_num);
374380

375381
/** Gets instructions from rename and inserts them into the ROB. */
376-
void getInsts();
382+
void moveInstsToBuffer();
377383

378384
/** Squash instructions in the rename to ROB TimeBuffer. */
379385
void squashInflightAndUpdateVersion(ThreadID tid);

0 commit comments

Comments
 (0)