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 + -
显示快捷键?