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 *> ¶mList = 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 + -
显示快捷键?