lsq_impl.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 628 行
HH
628 行
/* * Copyright (c) 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: Korey L. Sewell */#include <algorithm>#include <list>#include <string>#include "cpu/o3/lsq.hh"template<class Impl>voidLSQ<Impl>::DcachePort::setPeer(Port *port){ Port::setPeer(port);#if FULL_SYSTEM // Update the ThreadContext's memory ports (Functional/Virtual // Ports) lsq->updateMemPorts();#endif}template <class Impl>TickLSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt){ panic("O3CPU model does not work with atomic mode!"); return curTick;}template <class Impl>voidLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt){ DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.");}template <class Impl>voidLSQ<Impl>::DcachePort::recvStatusChange(Status status){ if (status == RangeChange) { if (!snoopRangeSent) { snoopRangeSent = true; sendStatusChange(Port::RangeChange); } return; } panic("O3CPU doesn't expect recvStatusChange callback!");}template <class Impl>boolLSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt){ if (pkt->isError()) DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr()); if (pkt->isResponse()) { lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt); } else { // must be a snoop // @TODO someday may need to process invalidations in LSQ here // to provide stronger consistency model } return true;}template <class Impl>voidLSQ<Impl>::DcachePort::recvRetry(){ if (lsq->retryTid == -1) { //Squashed, so drop it return; } int curr_retry_tid = lsq->retryTid; // Speculatively clear the retry Tid. This will get set again if // the LSQUnit was unable to complete its access. lsq->retryTid = -1; lsq->thread[curr_retry_tid].recvRetry();}template <class Impl>LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params) : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this), LQEntries(params->LQEntries), SQEntries(params->SQEntries), numThreads(params->numberOfThreads), retryTid(-1){ dcachePort.snoopRangeSent = false; //**********************************************/ //************ Handle SMT Parameters ***********/ //**********************************************/ std::string policy = params->smtLSQPolicy; //Convert string to lowercase std::transform(policy.begin(), policy.end(), policy.begin(), (int(*)(int)) tolower); //Figure out fetch policy if (policy == "dynamic") { lsqPolicy = Dynamic; maxLQEntries = LQEntries; maxSQEntries = SQEntries; DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); } else if (policy == "partitioned") { lsqPolicy = Partitioned; //@todo:make work if part_amt doesnt divide evenly. maxLQEntries = LQEntries / numThreads; maxSQEntries = SQEntries / numThreads; DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " "%i entries per LQ | %i entries per SQ", maxLQEntries,maxSQEntries); } else if (policy == "threshold") { lsqPolicy = Threshold; assert(params->smtLSQThreshold > LQEntries); assert(params->smtLSQThreshold > SQEntries); //Divide up by threshold amount //@todo: Should threads check the max and the total //amount of the LSQ maxLQEntries = params->smtLSQThreshold; maxSQEntries = params->smtLSQThreshold; DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " "%i entries per LQ | %i entries per SQ", maxLQEntries,maxSQEntries); } else { assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," "Partitioned, Threshold}"); } //Initialize LSQs for (int tid=0; tid < numThreads; tid++) { thread[tid].init(cpu, iew_ptr, params, this, maxLQEntries, maxSQEntries, tid); thread[tid].setDcachePort(&dcachePort); }}template<class Impl>std::stringLSQ<Impl>::name() const{ return iewStage->name() + ".lsq";}template<class Impl>voidLSQ<Impl>::regStats(){ //Initialize LSQs for (int tid=0; tid < numThreads; tid++) { thread[tid].regStats(); }}template<class Impl>voidLSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr){ activeThreads = at_ptr; assert(activeThreads != 0);}template <class Impl>voidLSQ<Impl>::switchOut(){ for (int tid = 0; tid < numThreads; tid++) { thread[tid].switchOut(); }}template <class Impl>voidLSQ<Impl>::takeOverFrom(){ for (int tid = 0; tid < numThreads; tid++) { thread[tid].takeOverFrom(); }}template <class Impl>intLSQ<Impl>::entryAmount(int num_threads){ if (lsqPolicy == Partitioned) { return LQEntries / num_threads; } else { return 0; }}template <class Impl>voidLSQ<Impl>::resetEntries(){ if (lsqPolicy != Dynamic || numThreads > 1) { int active_threads = activeThreads->size(); int maxEntries; if (lsqPolicy == Partitioned) { maxEntries = LQEntries / active_threads; } else if (lsqPolicy == Threshold && active_threads == 1) { maxEntries = LQEntries; } else { maxEntries = LQEntries; } std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; resizeEntries(maxEntries, tid); } }}template<class Impl>voidLSQ<Impl>::removeEntries(unsigned tid){ thread[tid].clearLQ(); thread[tid].clearSQ();}template<class Impl>voidLSQ<Impl>::resizeEntries(unsigned size,unsigned tid){ thread[tid].resizeLQ(size); thread[tid].resizeSQ(size);}template<class Impl>voidLSQ<Impl>::tick(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; thread[tid].tick(); }}template<class Impl>voidLSQ<Impl>::insertLoad(DynInstPtr &load_inst){ unsigned tid = load_inst->threadNumber; thread[tid].insertLoad(load_inst);}template<class Impl>voidLSQ<Impl>::insertStore(DynInstPtr &store_inst){ unsigned tid = store_inst->threadNumber; thread[tid].insertStore(store_inst);}template<class Impl>FaultLSQ<Impl>::executeLoad(DynInstPtr &inst){ unsigned tid = inst->threadNumber; return thread[tid].executeLoad(inst);}template<class Impl>FaultLSQ<Impl>::executeStore(DynInstPtr &inst){ unsigned tid = inst->threadNumber; return thread[tid].executeStore(inst);}template<class Impl>voidLSQ<Impl>::writebackStores(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (numStoresToWB(tid) > 0) { DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " "available for Writeback.\n", tid, numStoresToWB(tid)); } thread[tid].writebackStores(); }}template<class Impl>boolLSQ<Impl>::violation(){ /* Answers: Does Anybody Have a Violation?*/ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (thread[tid].violation()) return true; } return false;}template<class Impl>intLSQ<Impl>::getCount(){ unsigned total = 0; std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; total += getCount(tid); } return total;}template<class Impl>intLSQ<Impl>::numLoads(){ unsigned total = 0; std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; total += numLoads(tid); } return total;}template<class Impl>intLSQ<Impl>::numStores(){ unsigned total = 0; std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; total += thread[tid].numStores(); } return total;}template<class Impl>intLSQ<Impl>::numLoadsReady(){ unsigned total = 0; std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; total += thread[tid].numLoadsReady(); } return total;}template<class Impl>unsignedLSQ<Impl>::numFreeEntries(){ unsigned total = 0; std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; total += thread[tid].numFreeEntries(); } return total;}template<class Impl>unsignedLSQ<Impl>::numFreeEntries(unsigned tid){ //if (lsqPolicy == Dynamic) //return numFreeEntries(); //else return thread[tid].numFreeEntries();}template<class Impl>boolLSQ<Impl>::isFull(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (!(thread[tid].lqFull() || thread[tid].sqFull())) return false; } return true;}template<class Impl>boolLSQ<Impl>::isFull(unsigned tid){ //@todo: Change to Calculate All Entries for //Dynamic Policy if (lsqPolicy == Dynamic) return isFull(); else return thread[tid].lqFull() || thread[tid].sqFull();}template<class Impl>boolLSQ<Impl>::lqFull(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (!thread[tid].lqFull()) return false; } return true;}template<class Impl>boolLSQ<Impl>::lqFull(unsigned tid){ //@todo: Change to Calculate All Entries for //Dynamic Policy if (lsqPolicy == Dynamic) return lqFull(); else return thread[tid].lqFull();}template<class Impl>boolLSQ<Impl>::sqFull(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (!sqFull(tid)) return false; } return true;}template<class Impl>boolLSQ<Impl>::sqFull(unsigned tid){ //@todo: Change to Calculate All Entries for //Dynamic Policy if (lsqPolicy == Dynamic) return sqFull(); else return thread[tid].sqFull();}template<class Impl>boolLSQ<Impl>::isStalled(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (!thread[tid].isStalled()) return false; } return true;}template<class Impl>boolLSQ<Impl>::isStalled(unsigned tid){ if (lsqPolicy == Dynamic) return isStalled(); else return thread[tid].isStalled();}template<class Impl>boolLSQ<Impl>::hasStoresToWB(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); if (threads == end) return false; while (threads != end) { unsigned tid = *threads++; if (!hasStoresToWB(tid)) return false; } return true;}template<class Impl>boolLSQ<Impl>::willWB(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; if (!willWB(tid)) return false; } return true;}template<class Impl>voidLSQ<Impl>::dumpInsts(){ std::list<unsigned>::iterator threads = activeThreads->begin(); std::list<unsigned>::iterator end = activeThreads->end(); while (threads != end) { unsigned tid = *threads++; thread[tid].dumpInsts(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?