diff options
author | Gabor Dozsa <gabor.dozsa@arm.com> | 2018-06-25 16:59:26 +0100 |
---|---|---|
committer | Gabor Dozsa <gabor.dozsa@arm.com> | 2019-02-22 12:16:20 +0000 |
commit | 397d322b9952d264a99f025b026936aa7c2ed9cc (patch) | |
tree | 5dff2562a62c9d7973186c1e16042c3108007c55 | |
parent | 7d71f6641fcb660de0f003e2c028b464d7116ca1 (diff) | |
download | gem5-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.py | 4 | ||||
-rw-r--r-- | src/cpu/o3/lsq.hh | 10 | ||||
-rw-r--r-- | src/cpu/o3/lsq_impl.hh | 33 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 8 |
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; } |