summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabor Dozsa <gabor.dozsa@arm.com>2018-06-25 16:59:26 +0100
committerGabor Dozsa <gabor.dozsa@arm.com>2019-02-22 12:16:20 +0000
commit397d322b9952d264a99f025b026936aa7c2ed9cc (patch)
tree5dff2562a62c9d7973186c1e16042c3108007c55
parent7d71f6641fcb660de0f003e2c028b464d7116ca1 (diff)
downloadgem5-397d322b9952d264a99f025b026936aa7c2ed9cc.tar.xz
cpu-o3: Add cache read ports limit to LSQ
This change introduces cache read ports to limit the number of per-cycle loads. Previously only the number of per-cycle stores could be limited. Change-Id: I39bbd984056c5a696725ee2db462a55b2079e2d4 Signed-off-by: Gabor Dozsa <gabor.dozsa@arm.com> Reviewed-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/13517 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
-rw-r--r--src/cpu/o3/O3CPU.py4
-rw-r--r--src/cpu/o3/lsq.hh10
-rw-r--r--src/cpu/o3/lsq_impl.hh33
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh8
4 files changed, 42 insertions, 13 deletions
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index 8e17d9a3f..4a994f07f 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -77,7 +77,9 @@ class DerivO3CPU(BaseCPU):
activity = Param.Unsigned(0, "Initial count")
cacheStorePorts = Param.Unsigned(200, "Cache Ports. "
- "Constrains stores only. Loads are constrained by load FUs.")
+ "Constrains stores only.")
+ cacheLoadPorts = Param.Unsigned(200, "Cache Ports. "
+ "Constrains loads only.")
decodeToFetchDelay = Param.Cycles(1, "Decode to fetch delay")
renameToFetchDelay = Param.Cycles(1 ,"Rename to fetch delay")
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index f576dd3f4..a6037b7f4 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -755,7 +755,7 @@ class LSQ
int entryAmount(ThreadID num_threads);
/** Ticks the LSQ. */
- void tick() { usedStorePorts = 0; }
+ void tick();
/** Inserts a load into the LSQ. */
void insertLoad(const DynInstPtr &load_inst);
@@ -962,9 +962,9 @@ class LSQ
/** Set D-cache blocked status */
void cacheBlocked(bool v);
/** Is any store port available to use? */
- bool storePortAvailable() const;
+ bool cachePortAvailable(bool is_load) const;
/** Another store port is in use */
- void storePortBusy();
+ void cachePortBusy(bool is_load);
protected:
/** D-cache is blocked */
@@ -973,6 +973,10 @@ class LSQ
int cacheStorePorts;
/** The number of used cache ports in this cycle by stores. */
int usedStorePorts;
+ /** The number of cache ports available each cycle (loads only). */
+ int cacheLoadPorts;
+ /** The number of used cache ports in this cycle by loads. */
+ int usedLoadPorts;
/** The LSQ policy for SMT mode. */
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 5c64377b9..732712029 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -63,6 +63,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
: cpu(cpu_ptr), iewStage(iew_ptr),
_cacheBlocked(false),
cacheStorePorts(params->cacheStorePorts), usedStorePorts(0),
+ cacheLoadPorts(params->cacheLoadPorts), usedLoadPorts(0),
lsqPolicy(params->smtLSQPolicy),
LQEntries(params->LQEntries),
SQEntries(params->SQEntries),
@@ -173,6 +174,18 @@ LSQ<Impl>::takeOverFrom()
}
}
+template <class Impl>
+void
+LSQ<Impl>::tick()
+{
+ // Re-issue loads which got blocked on the per-cycle load ports limit.
+ if (usedLoadPorts == cacheLoadPorts && !_cacheBlocked)
+ iewStage->cacheUnblocked();
+
+ usedLoadPorts = 0;
+ usedStorePorts = 0;
+}
+
template<class Impl>
bool
LSQ<Impl>::cacheBlocked() const
@@ -189,17 +202,27 @@ LSQ<Impl>::cacheBlocked(bool v)
template<class Impl>
bool
-LSQ<Impl>::storePortAvailable() const
+LSQ<Impl>::cachePortAvailable(bool is_load) const
{
- return usedStorePorts < cacheStorePorts;
+ bool ret;
+ if (is_load) {
+ ret = usedLoadPorts < cacheLoadPorts;
+ } else {
+ ret = usedStorePorts < cacheStorePorts;
+ }
+ return ret;
}
template<class Impl>
void
-LSQ<Impl>::storePortBusy()
+LSQ<Impl>::cachePortBusy(bool is_load)
{
- usedStorePorts++;
- assert(usedStorePorts <= cacheStorePorts);
+ assert(cachePortAvailable(is_load));
+ if (is_load) {
+ usedLoadPorts++;
+ } else {
+ usedStorePorts++;
+ }
}
template<class Impl>
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 48179ceb8..2c59d5a9e 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -708,7 +708,7 @@ LSQUnit<Impl>::writebackStores()
storeWBIt->valid() &&
storeWBIt->canWB() &&
((!needsTSO) || (!storeInFlight)) &&
- lsq->storePortAvailable()) {
+ lsq->cachePortAvailable(false)) {
if (isStoreBlocked) {
DPRINTF(LSQUnit, "Unable to write back any more stores, cache"
@@ -1040,7 +1040,8 @@ LSQUnit<Impl>::trySendPacket(bool isLoad, PacketPtr data_pkt)
auto state = dynamic_cast<LSQSenderState*>(data_pkt->senderState);
- if (!lsq->cacheBlocked() && (isLoad || lsq->storePortAvailable())) {
+ if (!lsq->cacheBlocked() &&
+ lsq->cachePortAvailable(isLoad)) {
if (!dcachePort->sendTimingReq(data_pkt)) {
ret = false;
cache_got_blocked = true;
@@ -1051,9 +1052,9 @@ LSQUnit<Impl>::trySendPacket(bool isLoad, PacketPtr data_pkt)
if (ret) {
if (!isLoad) {
- lsq->storePortBusy();
isStoreBlocked = false;
}
+ lsq->cachePortBusy(isLoad);
state->outstanding++;
state->request()->packetSent();
} else {
@@ -1067,7 +1068,6 @@ LSQUnit<Impl>::trySendPacket(bool isLoad, PacketPtr data_pkt)
}
state->request()->packetNotSent();
}
-
return ret;
}