mem_dep_unit_impl.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 584 行 · 第 1/2 页
HH
584 行
storeBarrier = true; storeBarrierSN = barr_sn; DPRINTF(MemDepUnit, "Inserted a write barrier\n"); } unsigned tid = barr_inst->threadNumber; MemDepEntryPtr inst_entry = new MemDepEntry(barr_inst); // Add the MemDepEntry to the hash. memDepHash.insert( std::pair<InstSeqNum, MemDepEntryPtr>(barr_sn, inst_entry));#ifdef DEBUG MemDepEntry::memdep_insert++;#endif // Add the instruction to the instruction list. instList[tid].push_back(barr_inst); inst_entry->listIt = --(instList[tid].end());}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::regsReady(DynInstPtr &inst){ DPRINTF(MemDepUnit, "Marking registers as ready for " "instruction PC %#x [sn:%lli].\n", inst->readPC(), inst->seqNum); MemDepEntryPtr inst_entry = findInHash(inst); inst_entry->regsReady = true; if (inst_entry->memDepReady) { DPRINTF(MemDepUnit, "Instruction has its memory " "dependencies resolved, adding it to the ready list.\n"); moveToReady(inst_entry); } else { DPRINTF(MemDepUnit, "Instruction still waiting on " "memory dependency.\n"); }}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::nonSpecInstReady(DynInstPtr &inst){ DPRINTF(MemDepUnit, "Marking non speculative " "instruction PC %#x as ready [sn:%lli].\n", inst->readPC(), inst->seqNum); MemDepEntryPtr inst_entry = findInHash(inst); moveToReady(inst_entry);}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::reschedule(DynInstPtr &inst){ instsToReplay.push_back(inst);}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst){ DynInstPtr temp_inst; // For now this replay function replays all waiting memory ops. while (!instsToReplay.empty()) { temp_inst = instsToReplay.front(); MemDepEntryPtr inst_entry = findInHash(temp_inst); DPRINTF(MemDepUnit, "Replaying mem instruction PC %#x " "[sn:%lli].\n", temp_inst->readPC(), temp_inst->seqNum); moveToReady(inst_entry); instsToReplay.pop_front(); }}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::completed(DynInstPtr &inst){ DPRINTF(MemDepUnit, "Completed mem instruction PC %#x " "[sn:%lli].\n", inst->readPC(), inst->seqNum); unsigned tid = inst->threadNumber; // Remove the instruction from the hash and the list. MemDepHashIt hash_it = memDepHash.find(inst->seqNum); assert(hash_it != memDepHash.end()); instList[tid].erase((*hash_it).second->listIt); (*hash_it).second = NULL; memDepHash.erase(hash_it);#ifdef DEBUG MemDepEntry::memdep_erase++;#endif}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::completeBarrier(DynInstPtr &inst){ wakeDependents(inst); completed(inst); InstSeqNum barr_sn = inst->seqNum; if (inst->isMemBarrier()) { assert(loadBarrier && storeBarrier); if (loadBarrierSN == barr_sn) loadBarrier = false; if (storeBarrierSN == barr_sn) storeBarrier = false; } else if (inst->isWriteBarrier()) { assert(storeBarrier); if (storeBarrierSN == barr_sn) storeBarrier = false; }}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst){ // Only stores and barriers have dependents. if (!inst->isStore() && !inst->isMemBarrier() && !inst->isWriteBarrier()) { return; } MemDepEntryPtr inst_entry = findInHash(inst); for (int i = 0; i < inst_entry->dependInsts.size(); ++i ) { MemDepEntryPtr woken_inst = inst_entry->dependInsts[i]; if (!woken_inst->inst) { // Potentially removed mem dep entries could be on this list continue; } DPRINTF(MemDepUnit, "Waking up a dependent inst, " "[sn:%lli].\n", woken_inst->inst->seqNum); if (woken_inst->regsReady && !woken_inst->squashed) { moveToReady(woken_inst); } else { woken_inst->memDepReady = true; } } inst_entry->dependInsts.clear();}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num, unsigned tid){ if (!instsToReplay.empty()) { ListIt replay_it = instsToReplay.begin(); while (replay_it != instsToReplay.end()) { if ((*replay_it)->threadNumber == tid && (*replay_it)->seqNum > squashed_num) { instsToReplay.erase(replay_it++); } else { ++replay_it; } } } ListIt squash_it = instList[tid].end(); --squash_it; MemDepHashIt hash_it; while (!instList[tid].empty() && (*squash_it)->seqNum > squashed_num) { DPRINTF(MemDepUnit, "Squashing inst [sn:%lli]\n", (*squash_it)->seqNum); hash_it = memDepHash.find((*squash_it)->seqNum); assert(hash_it != memDepHash.end()); (*hash_it).second->squashed = true; (*hash_it).second = NULL; memDepHash.erase(hash_it);#ifdef DEBUG MemDepEntry::memdep_erase++;#endif instList[tid].erase(squash_it--); } // Tell the dependency predictor to squash as well. depPred.squash(squashed_num, tid);}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst, DynInstPtr &violating_load){ DPRINTF(MemDepUnit, "Passing violating PCs to store sets," " load: %#x, store: %#x\n", violating_load->readPC(), store_inst->readPC()); // Tell the memory dependence unit of the violation. depPred.violation(violating_load->readPC(), store_inst->readPC());}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst){ DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n", inst->readPC(), inst->seqNum); depPred.issued(inst->readPC(), inst->seqNum, inst->isStore());}template <class MemDepPred, class Impl>inline typename MemDepUnit<MemDepPred,Impl>::MemDepEntryPtr &MemDepUnit<MemDepPred, Impl>::findInHash(const DynInstPtr &inst){ MemDepHashIt hash_it = memDepHash.find(inst->seqNum); assert(hash_it != memDepHash.end()); return (*hash_it).second;}template <class MemDepPred, class Impl>inline voidMemDepUnit<MemDepPred, Impl>::moveToReady(MemDepEntryPtr &woken_inst_entry){ DPRINTF(MemDepUnit, "Adding instruction [sn:%lli] " "to the ready list.\n", woken_inst_entry->inst->seqNum); assert(!woken_inst_entry->squashed); iqPtr->addReadyMemInst(woken_inst_entry->inst);}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::dumpLists(){ for (unsigned tid=0; tid < Impl::MaxThreads; tid++) { cprintf("Instruction list %i size: %i\n", tid, instList[tid].size()); ListIt inst_list_it = instList[tid].begin(); int num = 0; while (inst_list_it != instList[tid].end()) { cprintf("Instruction:%i\nPC:%#x\n[sn:%i]\n[tid:%i]\nIssued:%i\n" "Squashed:%i\n\n", num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum, (*inst_list_it)->threadNumber, (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed()); inst_list_it++; ++num; } } cprintf("Memory dependence hash size: %i\n", memDepHash.size());#ifdef DEBUG cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);#endif}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?