commit_impl.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 1,375 行 · 第 1/3 页
HH
1,375 行
/* * Copyright (c) 2004, 2005, 2006 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Kevin T. Lim * Korey L. Sewell */#include "config/full_system.hh"#include "config/use_checker.hh"#include <algorithm>#include <string>#include "arch/utility.hh"#include "base/loader/symtab.hh"#include "base/timebuf.hh"#include "cpu/exetrace.hh"#include "cpu/o3/commit.hh"#include "cpu/o3/thread_state.hh"#if USE_CHECKER#include "cpu/checker/cpu.hh"#endiftemplate <class Impl>DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit, unsigned _tid) : Event(&mainEventQueue, CPU_Tick_Pri), commit(_commit), tid(_tid){ this->setFlags(Event::AutoDelete);}template <class Impl>voidDefaultCommit<Impl>::TrapEvent::process(){ // This will get reset by commit if it was switched out at the // time of this event processing. commit->trapSquash[tid] = true;}template <class Impl>const char *DefaultCommit<Impl>::TrapEvent::description() const{ return "Trap";}template <class Impl>DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *params) : cpu(_cpu), squashCounter(0), iewToCommitDelay(params->iewToCommitDelay), commitToIEWDelay(params->commitToIEWDelay), renameToROBDelay(params->renameToROBDelay), fetchToCommitDelay(params->commitToFetchDelay), renameWidth(params->renameWidth), commitWidth(params->commitWidth), numThreads(params->numberOfThreads), drainPending(false), switchedOut(false), trapLatency(params->trapLatency){ _status = Active; _nextStatus = Inactive; std::string policy = params->smtCommitPolicy; //Convert string to lowercase std::transform(policy.begin(), policy.end(), policy.begin(), (int(*)(int)) tolower); //Assign commit policy if (policy == "aggressive"){ commitPolicy = Aggressive; DPRINTF(Commit,"Commit Policy set to Aggressive."); } else if (policy == "roundrobin"){ commitPolicy = RoundRobin; //Set-Up Priority List for (int tid=0; tid < numThreads; tid++) { priority_list.push_back(tid); } DPRINTF(Commit,"Commit Policy set to Round Robin."); } else if (policy == "oldestready"){ commitPolicy = OldestReady; DPRINTF(Commit,"Commit Policy set to Oldest Ready."); } else { assert(0 && "Invalid SMT Commit Policy. Options Are: {Aggressive," "RoundRobin,OldestReady}"); } for (int i=0; i < numThreads; i++) { commitStatus[i] = Idle; changedROBNumEntries[i] = false; checkEmptyROB[i] = false; trapInFlight[i] = false; committedStores[i] = false; trapSquash[i] = false; tcSquash[i] = false; microPC[i] = nextMicroPC[i] = PC[i] = nextPC[i] = nextNPC[i] = 0; }#if FULL_SYSTEM interrupt = NoFault;#endif}template <class Impl>std::stringDefaultCommit<Impl>::name() const{ return cpu->name() + ".commit";}template <class Impl>voidDefaultCommit<Impl>::regStats(){ using namespace Stats; commitCommittedInsts .name(name() + ".commitCommittedInsts") .desc("The number of committed instructions") .prereq(commitCommittedInsts); commitSquashedInsts .name(name() + ".commitSquashedInsts") .desc("The number of squashed insts skipped by commit") .prereq(commitSquashedInsts); commitSquashEvents .name(name() + ".commitSquashEvents") .desc("The number of times commit is told to squash") .prereq(commitSquashEvents); commitNonSpecStalls .name(name() + ".commitNonSpecStalls") .desc("The number of times commit has been forced to stall to " "communicate backwards") .prereq(commitNonSpecStalls); branchMispredicts .name(name() + ".branchMispredicts") .desc("The number of times a branch was mispredicted") .prereq(branchMispredicts); numCommittedDist .init(0,commitWidth,1) .name(name() + ".COM:committed_per_cycle") .desc("Number of insts commited each cycle") .flags(Stats::pdf) ; statComInst .init(cpu->number_of_threads) .name(name() + ".COM:count") .desc("Number of instructions committed") .flags(total) ; statComSwp .init(cpu->number_of_threads) .name(name() + ".COM:swp_count") .desc("Number of s/w prefetches committed") .flags(total) ; statComRefs .init(cpu->number_of_threads) .name(name() + ".COM:refs") .desc("Number of memory references committed") .flags(total) ; statComLoads .init(cpu->number_of_threads) .name(name() + ".COM:loads") .desc("Number of loads committed") .flags(total) ; statComMembars .init(cpu->number_of_threads) .name(name() + ".COM:membars") .desc("Number of memory barriers committed") .flags(total) ; statComBranches .init(cpu->number_of_threads) .name(name() + ".COM:branches") .desc("Number of branches committed") .flags(total) ; commitEligible .init(cpu->number_of_threads) .name(name() + ".COM:bw_limited") .desc("number of insts not committed due to BW limits") .flags(total) ; commitEligibleSamples .name(name() + ".COM:bw_lim_events") .desc("number cycles where commit BW limit reached") ;}template <class Impl>voidDefaultCommit<Impl>::setThreads(std::vector<Thread *> &threads){ thread = threads;}template <class Impl>voidDefaultCommit<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr){ timeBuffer = tb_ptr; // Setup wire to send information back to IEW. toIEW = timeBuffer->getWire(0); // Setup wire to read data from IEW (for the ROB). robInfoFromIEW = timeBuffer->getWire(-iewToCommitDelay);}template <class Impl>voidDefaultCommit<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr){ fetchQueue = fq_ptr; // Setup wire to get instructions from rename (for the ROB). fromFetch = fetchQueue->getWire(-fetchToCommitDelay);}template <class Impl>voidDefaultCommit<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr){ renameQueue = rq_ptr; // Setup wire to get instructions from rename (for the ROB). fromRename = renameQueue->getWire(-renameToROBDelay);}template <class Impl>voidDefaultCommit<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr){ iewQueue = iq_ptr; // Setup wire to get instructions from IEW. fromIEW = iewQueue->getWire(-iewToCommitDelay);}template <class Impl>voidDefaultCommit<Impl>::setIEWStage(IEW *iew_stage){ iewStage = iew_stage;}template<class Impl>voidDefaultCommit<Impl>::setActiveThreads(std::list<unsigned> *at_ptr){ activeThreads = at_ptr;}template <class Impl>voidDefaultCommit<Impl>::setRenameMap(RenameMap rm_ptr[]){ for (int i=0; i < numThreads; i++) { renameMap[i] = &rm_ptr[i]; }}template <class Impl>voidDefaultCommit<Impl>::setROB(ROB *rob_ptr){ rob = rob_ptr;}template <class Impl>voidDefaultCommit<Impl>::initStage(){ rob->setActiveThreads(activeThreads); rob->resetEntries(); // Broadcast the number of free entries. for (int i=0; i < numThreads; i++) { toIEW->commitInfo[i].usedROB = true; toIEW->commitInfo[i].freeROBEntries = rob->numFreeEntries(i); toIEW->commitInfo[i].emptyROB = true; } // Commit must broadcast the number of free entries it has at the // start of the simulation, so it starts as active. cpu->activateStage(O3CPU::CommitIdx); cpu->activityThisCycle(); trapLatency = cpu->ticks(trapLatency);}template <class Impl>boolDefaultCommit<Impl>::drain(){ drainPending = true; return false;}template <class Impl>voidDefaultCommit<Impl>::switchOut(){ switchedOut = true; drainPending = false; rob->switchOut();}template <class Impl>voidDefaultCommit<Impl>::resume(){ drainPending = false;}template <class Impl>voidDefaultCommit<Impl>::takeOverFrom(){ switchedOut = false; _status = Active; _nextStatus = Inactive; for (int i=0; i < numThreads; i++) { commitStatus[i] = Idle; changedROBNumEntries[i] = false; trapSquash[i] = false; tcSquash[i] = false; } squashCounter = 0; rob->takeOverFrom();}template <class Impl>voidDefaultCommit<Impl>::updateStatus(){ // reset ROB changed variable std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; changedROBNumEntries[tid] = false; // Also check if any of the threads has a trap pending if (commitStatus[tid] == TrapPending || commitStatus[tid] == FetchTrapPending) { _nextStatus = Active; } } if (_nextStatus == Inactive && _status == Active) { DPRINTF(Activity, "Deactivating stage.\n"); cpu->deactivateStage(O3CPU::CommitIdx); } else if (_nextStatus == Active && _status == Inactive) { DPRINTF(Activity, "Activating stage.\n"); cpu->activateStage(O3CPU::CommitIdx); } _status = _nextStatus;}template <class Impl>voidDefaultCommit<Impl>::setNextStatus(){ int squashes = 0; std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (commitStatus[tid] == ROBSquashing) { squashes++; } } squashCounter = squashes; // If commit is currently squashing, then it will have activity for the // next cycle. Set its next status as active. if (squashCounter) { _nextStatus = Active; }}template <class Impl>boolDefaultCommit<Impl>::changedROBEntries(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (changedROBNumEntries[tid]) { return true; } } return false;}template <class Impl>unsignedDefaultCommit<Impl>::numROBFreeEntries(unsigned tid){ return rob->numFreeEntries(tid);}template <class Impl>voidDefaultCommit<Impl>::generateTrapEvent(unsigned tid){ DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?