fu_pool.cc

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

CC
283
字号
/* * Copyright (c) 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 */#include <sstream>#include "cpu/o3/fu_pool.hh"#include "cpu/func_unit.hh"using namespace std;////////////////////////////////////////////////////////////////////////////////  A pool of function units//inline voidFUPool::FUIdxQueue::addFU(int fu_idx){    funcUnitsIdx.push_back(fu_idx);    ++size;}inline intFUPool::FUIdxQueue::getFU(){    int retval = funcUnitsIdx[idx++];    if (idx == size)        idx = 0;    return retval;}FUPool::~FUPool(){    fuListIterator i = funcUnits.begin();    fuListIterator end = funcUnits.end();    for (; i != end; ++i)        delete *i;}// ConstructorFUPool::FUPool(const Params *p)    : SimObject(p){    numFU = 0;    funcUnits.clear();    for (int i = 0; i < Num_OpClasses; ++i) {        maxOpLatencies[i] = 0;        maxIssueLatencies[i] = 0;    }    //    //  Iterate through the list of FUDescData structures    //    const vector<FUDesc *> &paramList =  p->FUList;    for (FUDDiterator i = paramList.begin(); i != paramList.end(); ++i) {        //        //  Don't bother with this if we're not going to create any FU's        //        if ((*i)->number) {            //            //  Create the FuncUnit object from this structure            //   - add the capabilities listed in the FU's operation            //     description            //            //  We create the first unit, then duplicate it as needed            //            FuncUnit *fu = new FuncUnit;            OPDDiterator j = (*i)->opDescList.begin();            OPDDiterator end = (*i)->opDescList.end();            for (; j != end; ++j) {                // indicate that this pool has this capability                capabilityList.set((*j)->opClass);                // Add each of the FU's that will have this capability to the                // appropriate queue.                for (int k = 0; k < (*i)->number; ++k)                    fuPerCapList[(*j)->opClass].addFU(numFU + k);                // indicate that this FU has the capability                fu->addCapability((*j)->opClass, (*j)->opLat, (*j)->issueLat);                if ((*j)->opLat > maxOpLatencies[(*j)->opClass])                    maxOpLatencies[(*j)->opClass] = (*j)->opLat;                if ((*j)->issueLat > maxIssueLatencies[(*j)->opClass])                    maxIssueLatencies[(*j)->opClass] = (*j)->issueLat;            }            numFU++;            //  Add the appropriate number of copies of this FU to the list            ostringstream s;            s << (*i)->name() << "(0)";            fu->name = s.str();            funcUnits.push_back(fu);            for (int c = 1; c < (*i)->number; ++c) {                ostringstream s;                numFU++;                FuncUnit *fu2 = new FuncUnit(*fu);                s << (*i)->name() << "(" << c << ")";                fu2->name = s.str();                funcUnits.push_back(fu2);            }        }    }    unitBusy.resize(numFU);    for (int i = 0; i < numFU; i++) {        unitBusy[i] = false;    }}voidFUPool::annotateMemoryUnits(unsigned hit_latency){    maxOpLatencies[MemReadOp] = hit_latency;    fuListIterator i = funcUnits.begin();    fuListIterator iend = funcUnits.end();    for (; i != iend; ++i) {        if ((*i)->provides(MemReadOp))            (*i)->opLatency(MemReadOp) = hit_latency;        if ((*i)->provides(MemWriteOp))            (*i)->opLatency(MemWriteOp) = hit_latency;    }}intFUPool::getUnit(OpClass capability){    //  If this pool doesn't have the specified capability,    //  return this information to the caller    if (!capabilityList[capability])        return -2;    int fu_idx = fuPerCapList[capability].getFU();    int start_idx = fu_idx;    // Iterate through the circular queue if needed, stopping if we've reached    // the first element again.    while (unitBusy[fu_idx]) {        fu_idx = fuPerCapList[capability].getFU();        if (fu_idx == start_idx) {            // No FU available            return -1;        }    }    assert(fu_idx < numFU);    unitBusy[fu_idx] = true;    return fu_idx;}voidFUPool::freeUnitNextCycle(int fu_idx){    assert(unitBusy[fu_idx]);    unitsToBeFreed.push_back(fu_idx);}voidFUPool::processFreeUnits(){    while (!unitsToBeFreed.empty()) {        int fu_idx = unitsToBeFreed.back();        unitsToBeFreed.pop_back();        assert(unitBusy[fu_idx]);        unitBusy[fu_idx] = false;    }}voidFUPool::dump(){    cout << "Function Unit Pool (" << name() << ")\n";    cout << "======================================\n";    cout << "Free List:\n";    for (int i = 0; i < numFU; ++i) {        if (unitBusy[i]) {            continue;        }        cout << "  [" << i << "] : ";        cout << funcUnits[i]->name << " ";        cout << "\n";    }    cout << "======================================\n";    cout << "Busy List:\n";    for (int i = 0; i < numFU; ++i) {        if (!unitBusy[i]) {            continue;        }        cout << "  [" << i << "] : ";        cout << funcUnits[i]->name << " ";        cout << "\n";    }}voidFUPool::switchOut(){}voidFUPool::takeOverFrom(){    for (int i = 0; i < numFU; i++) {        unitBusy[i] = false;    }    unitsToBeFreed.clear();}//////////////////////////////////////////////////////////////////////////////////  The SimObjects we use to get the FU information into the simulator//////////////////////////////////////////////////////////////////////////////////    FUPool - Contails a list of FUDesc objects to make available//////  The FuPool object//FUPool *FUPoolParams::create(){    return new FUPool(this);}

⌨️ 快捷键说明

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