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