cpu-o3: Make the smtLSQPolicy a Param.ScopedEnum
The smtLSQPolicy is a parameter in the o3 cpu that can have 3 different values. Previously this setting was done through a string and a parser function would turn it into a c++ enum value. This changeset turns the string into a python Param.ScopedEnum. Change-Id: I82041b88bd914c5dc660058d9e3998e3114e7c35 Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/15397 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
@@ -51,6 +51,9 @@ from BranchPredictor import *
|
||||
class FetchPolicy(ScopedEnum):
|
||||
vals = [ 'SingleThread', 'RoundRobin', 'Branch', 'IQCount', 'LSQCount' ]
|
||||
|
||||
class SMTQueuePolicy(ScopedEnum):
|
||||
vals = [ 'Dynamic', 'Partitioned', 'Threshold' ]
|
||||
|
||||
class DerivO3CPU(BaseCPU):
|
||||
type = 'DerivO3CPU'
|
||||
cxx_header = 'cpu/o3/deriv.hh'
|
||||
@@ -151,7 +154,8 @@ class DerivO3CPU(BaseCPU):
|
||||
|
||||
smtNumFetchingThreads = Param.Unsigned(1, "SMT Number of Fetching Threads")
|
||||
smtFetchPolicy = Param.FetchPolicy('SingleThread', "SMT Fetch policy")
|
||||
smtLSQPolicy = Param.String('Partitioned', "SMT LSQ Sharing Policy")
|
||||
smtLSQPolicy = Param.SMTQueuePolicy('Partitioned',
|
||||
"SMT LSQ Sharing Policy")
|
||||
smtLSQThreshold = Param.Int(100, "SMT LSQ Threshold Sharing Parameter")
|
||||
smtIQPolicy = Param.String('Partitioned', "SMT IQ Sharing Policy")
|
||||
smtIQThreshold = Param.Int(100, "SMT IQ Threshold Sharing Parameter")
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
#include "cpu/o3/lsq_unit.hh"
|
||||
#include "cpu/inst_seq.hh"
|
||||
#include "enums/SMTQueuePolicy.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
@@ -62,13 +63,6 @@ class LSQ {
|
||||
typedef typename Impl::CPUPol::IEW IEW;
|
||||
typedef typename Impl::CPUPol::LSQUnit LSQUnit;
|
||||
|
||||
/** SMT policy. */
|
||||
enum LSQPolicy {
|
||||
Dynamic,
|
||||
Partitioned,
|
||||
Threshold
|
||||
};
|
||||
|
||||
/** Constructs an LSQ with the given parameters. */
|
||||
LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params);
|
||||
~LSQ() { }
|
||||
@@ -306,40 +300,21 @@ class LSQ {
|
||||
|
||||
protected:
|
||||
/** The LSQ policy for SMT mode. */
|
||||
LSQPolicy lsqPolicy;
|
||||
|
||||
/** 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;
|
||||
}
|
||||
SMTQueuePolicy lsqPolicy;
|
||||
|
||||
/** 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,
|
||||
static uint32_t maxLSQAllocation(SMTQueuePolicy pol, uint32_t entries,
|
||||
uint32_t numThreads, uint32_t SMTThreshold) {
|
||||
if (pol == Dynamic) {
|
||||
if (pol == SMTQueuePolicy::Dynamic) {
|
||||
return entries;
|
||||
} else if (pol == Partitioned) {
|
||||
} else if (pol == SMTQueuePolicy::Partitioned) {
|
||||
//@todo:make work if part_amt doesnt divide evenly.
|
||||
return entries / numThreads;
|
||||
} else if (pol == Threshold) {
|
||||
} else if (pol == SMTQueuePolicy::Threshold) {
|
||||
//Divide up by threshold amount
|
||||
//@todo: Should threads check the max and the total
|
||||
//amount of the LSQ
|
||||
|
||||
@@ -61,7 +61,7 @@ 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)),
|
||||
lsqPolicy(params->smtLSQPolicy),
|
||||
LQEntries(params->LQEntries),
|
||||
SQEntries(params->SQEntries),
|
||||
maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads,
|
||||
@@ -77,13 +77,13 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
|
||||
//**********************************************/
|
||||
|
||||
//Figure out fetch policy
|
||||
if (lsqPolicy == Dynamic) {
|
||||
if (lsqPolicy == SMTQueuePolicy::Dynamic) {
|
||||
DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
|
||||
} else if (lsqPolicy == Partitioned) {
|
||||
} else if (lsqPolicy == SMTQueuePolicy::Partitioned) {
|
||||
DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
|
||||
"%i entries per LQ | %i entries per SQ\n",
|
||||
maxLQEntries,maxSQEntries);
|
||||
} else if (lsqPolicy == Threshold) {
|
||||
} else if (lsqPolicy == SMTQueuePolicy::Threshold) {
|
||||
|
||||
assert(params->smtLSQThreshold > LQEntries);
|
||||
assert(params->smtLSQThreshold > SQEntries);
|
||||
@@ -172,7 +172,7 @@ template <class Impl>
|
||||
int
|
||||
LSQ<Impl>::entryAmount(ThreadID num_threads)
|
||||
{
|
||||
if (lsqPolicy == Partitioned) {
|
||||
if (lsqPolicy == SMTQueuePolicy::Partitioned) {
|
||||
return LQEntries / num_threads;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -183,14 +183,15 @@ template <class Impl>
|
||||
void
|
||||
LSQ<Impl>::resetEntries()
|
||||
{
|
||||
if (lsqPolicy != Dynamic || numThreads > 1) {
|
||||
if (lsqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) {
|
||||
int active_threads = activeThreads->size();
|
||||
|
||||
int maxEntries;
|
||||
|
||||
if (lsqPolicy == Partitioned) {
|
||||
if (lsqPolicy == SMTQueuePolicy::Partitioned) {
|
||||
maxEntries = LQEntries / active_threads;
|
||||
} else if (lsqPolicy == Threshold && active_threads == 1) {
|
||||
} else if (lsqPolicy == SMTQueuePolicy::Threshold &&
|
||||
active_threads == 1) {
|
||||
maxEntries = LQEntries;
|
||||
} else {
|
||||
maxEntries = LQEntries;
|
||||
@@ -500,7 +501,7 @@ LSQ<Impl>::isFull(ThreadID tid)
|
||||
{
|
||||
//@todo: Change to Calculate All Entries for
|
||||
//Dynamic Policy
|
||||
if (lsqPolicy == Dynamic)
|
||||
if (lsqPolicy == SMTQueuePolicy::Dynamic)
|
||||
return isFull();
|
||||
else
|
||||
return thread[tid].lqFull() || thread[tid].sqFull();
|
||||
@@ -570,7 +571,7 @@ LSQ<Impl>::lqFull(ThreadID tid)
|
||||
{
|
||||
//@todo: Change to Calculate All Entries for
|
||||
//Dynamic Policy
|
||||
if (lsqPolicy == Dynamic)
|
||||
if (lsqPolicy == SMTQueuePolicy::Dynamic)
|
||||
return lqFull();
|
||||
else
|
||||
return thread[tid].lqFull();
|
||||
@@ -599,7 +600,7 @@ LSQ<Impl>::sqFull(ThreadID tid)
|
||||
{
|
||||
//@todo: Change to Calculate All Entries for
|
||||
//Dynamic Policy
|
||||
if (lsqPolicy == Dynamic)
|
||||
if (lsqPolicy == SMTQueuePolicy::Dynamic)
|
||||
return sqFull();
|
||||
else
|
||||
return thread[tid].sqFull();
|
||||
@@ -626,7 +627,7 @@ template<class Impl>
|
||||
bool
|
||||
LSQ<Impl>::isStalled(ThreadID tid)
|
||||
{
|
||||
if (lsqPolicy == Dynamic)
|
||||
if (lsqPolicy == SMTQueuePolicy::Dynamic)
|
||||
return isStalled();
|
||||
else
|
||||
return thread[tid].isStalled();
|
||||
|
||||
Reference in New Issue
Block a user