diff options
-rw-r--r-- | src/cpu/o3/dep_graph.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/lsq.hh | 48 | ||||
-rw-r--r-- | src/cpu/o3/lsq_impl.hh | 41 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit.hh | 11 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 26 |
5 files changed, 72 insertions, 59 deletions
diff --git a/src/cpu/o3/dep_graph.hh b/src/cpu/o3/dep_graph.hh index 212130e2b..2e866a6c5 100644 --- a/src/cpu/o3/dep_graph.hh +++ b/src/cpu/o3/dep_graph.hh @@ -122,7 +122,7 @@ class DependencyGraph * instructions in flight that are dependent upon r34 will be * in the linked list of dependGraph[34]. */ - DepEntry *dependGraph; + std::vector<DepEntry> dependGraph; /** Number of linked lists; identical to the number of registers. */ int numEntries; @@ -140,7 +140,6 @@ class DependencyGraph template <class DynInstPtr> DependencyGraph<DynInstPtr>::~DependencyGraph() { - delete [] dependGraph; } template <class DynInstPtr> @@ -148,7 +147,7 @@ void DependencyGraph<DynInstPtr>::resize(int num_entries) { numEntries = num_entries; - dependGraph = new DepEntry[numEntries]; + dependGraph.resize(numEntries); } template <class DynInstPtr> diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index 175821e69..0c93121e3 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -71,9 +71,7 @@ class LSQ { /** Constructs an LSQ with the given parameters. */ LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params); - ~LSQ() { - if (thread) delete [] thread; - } + ~LSQ() { } /** Returns the name of the LSQ. */ std::string name() const; @@ -310,8 +308,45 @@ class LSQ { /** The LSQ policy for SMT mode. */ LSQPolicy lsqPolicy; - /** The LSQ units for individual threads. */ - LSQUnit *thread; + /** Transform a SMT sharing policy string into a LSQPolicy value. */ + static LSQPolicy readLSQPolicy(const std::string& policy) { + std::string policy_ = policy; + std::transform(policy_.begin(), policy_.end(), policy_.begin(), + (int(*)(int)) tolower); + if (policy_ == "dynamic") { + return Dynamic; + } else if (policy_ == "partitioned") { + return Partitioned; + } else if (policy_ == "threshold") { + return Threshold; + } + assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," + "Partitioned, Threshold}"); + + // Some compilers complain if there is no return. + return Dynamic; + } + + /** Auxiliary function to calculate per-thread max LSQ allocation limit. + * Depending on a policy, number of entries and possibly number of threads + * and threshold, this function calculates how many resources each thread + * can occupy at most. + */ + static uint32_t maxLSQAllocation(const LSQPolicy& pol, uint32_t entries, + uint32_t numThreads, uint32_t SMTThreshold) { + if (pol == Dynamic) { + return entries; + } else if (pol == Partitioned) { + //@todo:make work if part_amt doesnt divide evenly. + return entries / numThreads; + } else if (pol == Threshold) { + //Divide up by threshold amount + //@todo: Should threads check the max and the total + //amount of the LSQ + return SMTThreshold; + } + return 0; + } /** List of Active Threads in System. */ std::list<ThreadID> *activeThreads; @@ -327,6 +362,9 @@ class LSQ { /** Max SQ Size - Used to Enforce Sharing Policies. */ unsigned maxSQEntries; + /** The LSQ units for individual threads. */ + std::vector<LSQUnit> thread; + /** Number of Threads. */ ThreadID numThreads; }; diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index 83de8ddff..36bc17bc8 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -61,8 +61,13 @@ using namespace std; template <class Impl> LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) : cpu(cpu_ptr), iewStage(iew_ptr), + lsqPolicy(readLSQPolicy(params->smtLSQPolicy)), LQEntries(params->LQEntries), SQEntries(params->SQEntries), + maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads, + params->smtLSQThreshold)), + maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, + params->smtLSQThreshold)), numThreads(params->numThreads) { assert(numThreads > 0 && numThreads <= Impl::MaxThreads); @@ -70,42 +75,19 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) //**********************************************/ //************ 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; - + if (lsqPolicy == Dynamic) { 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; - + } else if (lsqPolicy == Partitioned) { DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " "%i entries per LQ | %i entries per SQ\n", maxLQEntries,maxSQEntries); - } else if (policy == "threshold") { - lsqPolicy = Threshold; + } else if (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\n", maxLQEntries,maxSQEntries); @@ -114,11 +96,10 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) "Partitioned, Threshold"); } - //Initialize LSQs - thread = new LSQUnit[numThreads]; + thread.reserve(numThreads); for (ThreadID tid = 0; tid < numThreads; tid++) { - thread[tid].init(cpu, iew_ptr, params, this, - maxLQEntries, maxSQEntries, tid); + thread.emplace_back(maxLQEntries, maxSQEntries); + thread[tid].init(cpu, iew_ptr, params, this, tid); thread[tid].setDcachePort(&cpu_ptr->getDataPort()); } } diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index 813a3cac7..48a06b386 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -86,12 +86,17 @@ class LSQUnit { public: /** Constructs an LSQ unit. init() must be called prior to use. */ - LSQUnit(); + LSQUnit(uint32_t lqEntries, uint32_t sqEntries); + + /** We cannot copy LSQUnit because it has stats for which copy + * contructor is deleted explicitly. However, STL vector requires + * a valid copy constructor for the base type at compile time. + */ + LSQUnit(const LSQUnit &l) { panic("LSQUnit is not copy-able"); } /** Initializes the LSQ unit with the specified number of entries. */ void init(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params, - LSQ *lsq_ptr, unsigned maxLQEntries, unsigned maxSQEntries, - unsigned id); + LSQ *lsq_ptr, unsigned id); /** Returns the name of the LSQ unit. */ std::string name() const; diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index d8f1c39c6..5438c4d07 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -142,8 +142,10 @@ LSQUnit<Impl>::completeDataAccess(PacketPtr pkt) } template <class Impl> -LSQUnit<Impl>::LSQUnit() - : loads(0), stores(0), storesToWB(0), cacheBlockMask(0), stalled(false), +LSQUnit<Impl>::LSQUnit(uint32_t lqEntries, uint32_t sqEntries) + : lsqID(-1), storeQueue(sqEntries+1), loadQueue(lqEntries+1), + LQEntries(lqEntries+1), SQEntries(lqEntries+1), + loads(0), stores(0), storesToWB(0), cacheBlockMask(0), stalled(false), isStoreBlocked(false), storeInFlight(false), hasPendingPkt(false), pendingPkt(nullptr) { @@ -152,28 +154,16 @@ LSQUnit<Impl>::LSQUnit() template<class Impl> void LSQUnit<Impl>::init(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params, - LSQ *lsq_ptr, unsigned maxLQEntries, unsigned maxSQEntries, - unsigned id) + LSQ *lsq_ptr, unsigned id) { + lsqID = id; + cpu = cpu_ptr; iewStage = iew_ptr; lsq = lsq_ptr; - lsqID = id; - - DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",id); - - // Add 1 for the sentinel entry (they are circular queues). - LQEntries = maxLQEntries + 1; - SQEntries = maxSQEntries + 1; - - //Due to uint8_t index in LSQSenderState - assert(LQEntries <= 256); - assert(SQEntries <= 256); - - loadQueue.resize(LQEntries); - storeQueue.resize(SQEntries); + DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",lsqID); depCheckShift = params->LSQDepCheckShift; checkLoads = params->LSQCheckLoads; |