rob_impl.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 696 行 · 第 1/2 页

HH
696
字号
/* * 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 "cpu/o3/rob.hh"#include <list>template <class Impl>ROB<Impl>::ROB(O3CPU *_cpu, unsigned _numEntries, unsigned _squashWidth,               std::string _smtROBPolicy, unsigned _smtROBThreshold,               unsigned _numThreads)    : cpu(_cpu),      numEntries(_numEntries),      squashWidth(_squashWidth),      numInstsInROB(0),      numThreads(_numThreads){    for (int tid=0; tid  < numThreads; tid++) {        squashedSeqNum[tid] = 0;        doneSquashing[tid] = true;        threadEntries[tid] = 0;    }    std::string policy = _smtROBPolicy;    //Convert string to lowercase    std::transform(policy.begin(), policy.end(), policy.begin(),                   (int(*)(int)) tolower);    //Figure out rob policy    if (policy == "dynamic") {        robPolicy = Dynamic;        //Set Max Entries to Total ROB Capacity        for (int i = 0; i < numThreads; i++) {            maxEntries[i]=numEntries;        }    } else if (policy == "partitioned") {        robPolicy = Partitioned;        DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n");        //@todo:make work if part_amt doesnt divide evenly.        int part_amt = numEntries / numThreads;        //Divide ROB up evenly        for (int i = 0; i < numThreads; i++) {            maxEntries[i]=part_amt;        }    } else if (policy == "threshold") {        robPolicy = Threshold;        DPRINTF(Fetch, "ROB sharing policy set to Threshold\n");        int threshold =  _smtROBThreshold;;        //Divide up by threshold amount        for (int i = 0; i < numThreads; i++) {            maxEntries[i]=threshold;        }    } else {        assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic,"                    "Partitioned, Threshold}");    }    // Set the per-thread iterators to the end of the instruction list.    for (int i=0; i < numThreads;i++) {        squashIt[i] = instList[i].end();    }    // Initialize the "universal" ROB head & tail point to invalid    // pointers    head = instList[0].end();    tail = instList[0].end();}template <class Impl>std::stringROB<Impl>::name() const{    return cpu->name() + ".rob";}template <class Impl>voidROB<Impl>::setActiveThreads(std::list<unsigned> *at_ptr){    DPRINTF(ROB, "Setting active threads list pointer.\n");    activeThreads = at_ptr;}template <class Impl>voidROB<Impl>::switchOut(){    for (int tid = 0; tid < numThreads; tid++) {        instList[tid].clear();    }}template <class Impl>voidROB<Impl>::takeOverFrom(){    for (int tid=0; tid  < numThreads; tid++) {        doneSquashing[tid] = true;        threadEntries[tid] = 0;        squashIt[tid] = instList[tid].end();    }    numInstsInROB = 0;    // Initialize the "universal" ROB head & tail point to invalid    // pointers    head = instList[0].end();    tail = instList[0].end();}template <class Impl>voidROB<Impl>::resetEntries(){    if (robPolicy != Dynamic || numThreads > 1) {        int active_threads = activeThreads->size();        std::list<unsigned>::iterator threads = activeThreads->begin();        std::list<unsigned>::iterator end = activeThreads->end();        while (threads != end) {            unsigned tid = *threads++;            if (robPolicy == Partitioned) {                maxEntries[tid] = numEntries / active_threads;            } else if (robPolicy == Threshold && active_threads == 1) {                maxEntries[tid] = numEntries;            }        }    }}template <class Impl>intROB<Impl>::entryAmount(int num_threads){    if (robPolicy == Partitioned) {        return numEntries / num_threads;    } else {        return 0;    }}template <class Impl>intROB<Impl>::countInsts(){    int total=0;    for (int i=0;i < numThreads;i++)        total += countInsts(i);    return total;}template <class Impl>intROB<Impl>::countInsts(unsigned tid){    return instList[tid].size();}template <class Impl>voidROB<Impl>::insertInst(DynInstPtr &inst){    //assert(numInstsInROB == countInsts());    assert(inst);    DPRINTF(ROB, "Adding inst PC %#x to the ROB.\n", inst->readPC());    assert(numInstsInROB != numEntries);    int tid = inst->threadNumber;    instList[tid].push_back(inst);    //Set Up head iterator if this is the 1st instruction in the ROB    if (numInstsInROB == 0) {        head = instList[tid].begin();        assert((*head) == inst);    }    //Must Decrement for iterator to actually be valid  since __.end()    //actually points to 1 after the last inst    tail = instList[tid].end();    tail--;    inst->setInROB();    ++numInstsInROB;    ++threadEntries[tid];    assert((*tail) == inst);    DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]);}// Whatever calls this function needs to ensure that it properly frees up// registers prior to this function./*template <class Impl>voidROB<Impl>::retireHead(){    //assert(numInstsInROB == countInsts());    assert(numInstsInROB > 0);    int tid = (*head)->threadNumber;    retireHead(tid);    if (numInstsInROB == 0) {        tail = instList[tid].end();    }}*/template <class Impl>voidROB<Impl>::retireHead(unsigned tid){    //assert(numInstsInROB == countInsts());    assert(numInstsInROB > 0);    // Get the head ROB instruction.    InstIt head_it = instList[tid].begin();    DynInstPtr head_inst = (*head_it);    assert(head_inst->readyToCommit());    DPRINTF(ROB, "[tid:%u]: Retiring head instruction, "            "instruction PC %#x,[sn:%lli]\n", tid, head_inst->readPC(),            head_inst->seqNum);    --numInstsInROB;    --threadEntries[tid];    head_inst->clearInROB();    head_inst->setCommitted();    instList[tid].erase(head_it);    //Update "Global" Head of ROB    updateHead();    // @todo: A special case is needed if the instruction being    // retired is the only instruction in the ROB; otherwise the tail    // iterator will become invalidated.    cpu->removeFrontInst(head_inst);}/*template <class Impl>boolROB<Impl>::isHeadReady(){    if (numInstsInROB != 0) {        return (*head)->readyToCommit();    }    return false;}*/template <class Impl>boolROB<Impl>::isHeadReady(unsigned tid){    if (threadEntries[tid] != 0) {        return instList[tid].front()->readyToCommit();    }    return false;}template <class Impl>boolROB<Impl>::canCommit(){    //@todo: set ActiveThreads through ROB or CPU    std::list<unsigned>::iterator threads = activeThreads->begin();    std::list<unsigned>::iterator end = activeThreads->end();    while (threads != end) {        unsigned tid = *threads++;        if (isHeadReady(tid)) {            return true;        }    }    return false;}template <class Impl>unsignedROB<Impl>::numFreeEntries(){    //assert(numInstsInROB == countInsts());    return numEntries - numInstsInROB;}template <class Impl>unsignedROB<Impl>::numFreeEntries(unsigned tid){    return maxEntries[tid] - threadEntries[tid];}template <class Impl>void

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?