cpu-o3: bugfix of rename squash when SMT (#172)
In an SMT CPU, upon a squash, the mis-predicted(squashing) instructions can still be executing at IEW and own phys registers. If these registers are added back to the rename freelist on this Tick, the registers may be renamed to be used by other SMT thread(s). This causes register ownership hazards, which may eventually freeze the CPU. This problem seems to date back to 2014 (https://www.mail-archive.com/gem5-users@gem5.org/msg10180.html). This patch delays the freelist update to avoid the hazard. I tested that this patch does not cause any performance impact for my set of benchmarks on default non-SMT O3CPU.
This commit is contained in:
@@ -940,8 +940,11 @@ Rename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
|
||||
// previous physical register that it was renamed to.
|
||||
renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
|
||||
|
||||
// Put the renamed physical register back on the free list.
|
||||
freeList->addReg(hb_it->newPhysReg);
|
||||
// The phys regs can still be owned by squashing but
|
||||
// executing instructions in IEW at this moment. To avoid
|
||||
// ownership hazard in SMT CPU, we delay the freelist update
|
||||
// until they are indeed squashed in the commit stage.
|
||||
freeingInProgress[tid].push_back(hb_it->newPhysReg);
|
||||
}
|
||||
|
||||
// Notify potential listeners that the register mapping needs to be
|
||||
@@ -1296,6 +1299,18 @@ Rename::checkSignalsAndUpdate(ThreadID tid)
|
||||
squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
|
||||
|
||||
return true;
|
||||
} else if (!fromCommit->commitInfo[tid].robSquashing &&
|
||||
!freeingInProgress[tid].empty()) {
|
||||
DPRINTF(Rename, "[tid:%i] Freeing phys regs of misspeculated "
|
||||
"instructions.\n", tid);
|
||||
|
||||
auto reg_it = freeingInProgress[tid].cbegin();
|
||||
while ( reg_it != freeingInProgress[tid].cend()){
|
||||
// Put the renamed physical register back on the free list.
|
||||
freeList->addReg(*reg_it);
|
||||
++reg_it;
|
||||
}
|
||||
freeingInProgress[tid].clear();
|
||||
}
|
||||
|
||||
if (checkStall(tid)) {
|
||||
|
||||
@@ -359,6 +359,9 @@ class Rename
|
||||
/** Free list interface. */
|
||||
UnifiedFreeList *freeList;
|
||||
|
||||
/** Hold phys regs to be released after squash finish */
|
||||
std::vector<PhysRegIdPtr> freeingInProgress[MaxThreads];
|
||||
|
||||
/** Pointer to the list of active threads. */
|
||||
std::list<ThreadID> *activeThreads;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user