Hello Sudhanshu Jha, Nikos Nikoleris,
I'd like you to do a code review. Please visit
https://gem5-review.googlesource.com/c/public/gem5/+/18809
to review the following change.
Change subject: mem-cache: Add support for more than one prefetcher
......................................................................
mem-cache: Add support for more than one prefetcher
The cache currently only supports a single hardware
prefetcher. However, there are cases where it is desirable to have
multiple prefetchers active at any given moment.
This patch changes the prefetcher parameter into a vector. The cache
then uses the prefetch packet from the first prefetcher that is able
to generate a prefetch. That is, the prefetch vector is sorted in
priority order.
Change-Id: I64b4d8fd424012cb05f5754e6a5956b6ebd9cd0d
Signed-off-by: Andreas Sandberg <[email protected]>
Reviewed-by: Nikos Nikoleris <[email protected]>
Reviewed-by: Sudhanshu Jha <[email protected]>
---
M src/mem/cache/Cache.py
M src/mem/cache/base.cc
M src/mem/cache/base.hh
3 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py
index 7a28136..dabb016 100644
--- a/src/mem/cache/Cache.py
+++ b/src/mem/cache/Cache.py
@@ -97,7 +97,7 @@
is_read_only = Param.Bool(False, "Is this cache read only (e.g. inst)")
- prefetcher = Param.BasePrefetcher(NULL,"Prefetcher attached to cache")
+ prefetcher = VectorParam.BasePrefetcher([], "Prefetcher attached to
cache")
prefetch_on_access = Param.Bool(False,
"Notify the hardware prefetcher on every access (not just
misses)")
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 8929343..ca8d280 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -87,7 +87,7 @@
writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below
tags(p->tags),
compressor(p->compressor),
- prefetcher(p->prefetcher),
+ prefetchers(p->prefetcher.begin(), p->prefetcher.end()),
writeAllocator(p->write_allocator),
writebackClean(p->writeback_clean),
tempBlockWriteback(nullptr),
@@ -124,7 +124,7 @@
tempBlock = new TempCacheBlk(blkSize);
tags->tagsInit();
- if (prefetcher)
+ for (auto prefetcher : prefetchers)
prefetcher->setCache(this);
}
@@ -212,6 +212,31 @@
return false;
}
+Tick
+BaseCache::nextPrefetchReadyTick() const
+{
+ Tick next_ready = MaxTick;
+
+ for (auto prefetcher : prefetchers) {
+ Tick cur_ready = prefetcher->nextPrefetchReadyTime();
+ next_ready = std::min(next_ready, cur_ready);
+ }
+
+ return std::max(next_ready, clockEdge());
+}
+
+PacketPtr
+BaseCache::getPrefetchPacket()
+{
+ for (auto prefetcher : prefetchers) {
+ PacketPtr p = prefetcher->getPacket();
+ if (p)
+ return p;
+ }
+
+ return nullptr;
+}
+
void
BaseCache::handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick
request_time)
{
@@ -362,7 +387,7 @@
// the packet in a response
ppHit->notify(pkt);
- if (prefetcher && blk && blk->wasPrefetched()) {
+ if (!prefetchers.empty() && blk && blk->wasPrefetched()) {
blk->status &= ~BlkHWPrefetched;
}
@@ -373,13 +398,10 @@
ppMiss->notify(pkt);
}
- if (prefetcher) {
- // track time of availability of next prefetch, if any
- Tick next_pf_time = prefetcher->nextPrefetchReadyTime();
- if (next_pf_time != MaxTick) {
- schedMemSideSendEvent(next_pf_time);
- }
- }
+ // track time of availability of next prefetch, if any
+ Tick next_pf_time = nextPrefetchReadyTick();
+ if (next_pf_time != MaxTick)
+ schedMemSideSendEvent(next_pf_time);
}
void
@@ -510,9 +532,8 @@
// Request the bus for a prefetch if this deallocation freed enough
// MSHRs for a prefetch to take place
- if (prefetcher && mshrQueue.canPrefetch()) {
- Tick next_pf_time =
std::max(prefetcher->nextPrefetchReadyTime(),
- clockEdge());
+ if (mshrQueue.canPrefetch()) {
+ Tick next_pf_time = nextPrefetchReadyTick();
if (next_pf_time != MaxTick)
schedMemSideSendEvent(next_pf_time);
}
@@ -747,9 +768,9 @@
// fall through... no pending requests. Try a prefetch.
assert(!miss_mshr && !wq_entry);
- if (prefetcher && mshrQueue.canPrefetch()) {
+ if (mshrQueue.canPrefetch()) {
// If we have a miss queue slot, we can try a prefetch
- PacketPtr pkt = prefetcher->getPacket();
+ PacketPtr pkt = getPrefetchPacket();
if (pkt) {
Addr pf_addr = pkt->getBlockAddr(blkSize);
if (!tags->findBlock(pf_addr, pkt->isSecure()) &&
@@ -1715,11 +1736,9 @@
writeBuffer.nextReadyTime());
// Don't signal prefetch ready time if no MSHRs available
- // Will signal once enoguh MSHRs are deallocated
- if (prefetcher && mshrQueue.canPrefetch()) {
- nextReady = std::min(nextReady,
- prefetcher->nextPrefetchReadyTime());
- }
+ // Will signal once enough MSHRs are deallocated
+ if (mshrQueue.canPrefetch())
+ nextReady = std::min(nextReady, nextPrefetchReadyTick());
return nextReady;
}
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index bf190a5..93c34e6 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2015-2016, 2018 ARM Limited
+ * Copyright (c) 2012-2013, 2015-2016, 2018-2019 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -328,8 +328,8 @@
/** Compression method being used. */
BaseCacheCompressor* compressor;
- /** Prefetcher */
- BasePrefetcher *prefetcher;
+ /** Prefetchers */
+ std::list<BasePrefetcher *> prefetchers;
/** To probe when a cache hit occurs */
ProbePointArg<PacketPtr> *ppHit;
@@ -824,6 +824,17 @@
*/
Tick nextQueueReadyTime() const;
+ /**
+ * Determine when the next prefetch packet will be ready.
+ */
+ Tick nextPrefetchReadyTick() const;
+
+ /**
+ * Get a packet from a prefetch packet from one of the configured
+ * hardware prefetchers.
+ */
+ PacketPtr getPrefetchPacket();
+
/** Block size of this cache */
const unsigned blkSize;
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/18809
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I64b4d8fd424012cb05f5754e6a5956b6ebd9cd0d
Gerrit-Change-Number: 18809
Gerrit-PatchSet: 1
Gerrit-Owner: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Nikos Nikoleris <[email protected]>
Gerrit-Reviewer: Sudhanshu Jha <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev