diff options
author | Javier Bueno <javier.bueno@metempsy.com> | 2018-11-09 16:02:04 +0100 |
---|---|---|
committer | Javier Bueno Hedo <javier.bueno@metempsy.com> | 2018-11-14 14:19:05 +0000 |
commit | 8590243fef2e4ccaefde3af767496dec44c6eb33 (patch) | |
tree | 6cf26aa22f26864a116bfe33ab0069ddb7084906 /src/mem/cache/prefetch | |
parent | e8e92a12af8cc499659ad840c84c99e293ff1e96 (diff) | |
download | gem5-8590243fef2e4ccaefde3af767496dec44c6eb33.tar.xz |
mem-cache: implement a probe-based interface
The HW Prefetcher of a cache can now listen events
from their associated CPUs and from its own cache.
Change-Id: I28aecd8faf8ed44be94464d84485bd1cea2efae3
Reviewed-on: https://gem5-review.googlesource.com/c/14155
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Diffstat (limited to 'src/mem/cache/prefetch')
-rw-r--r-- | src/mem/cache/prefetch/Prefetcher.py | 36 | ||||
-rw-r--r-- | src/mem/cache/prefetch/base.cc | 47 | ||||
-rw-r--r-- | src/mem/cache/prefetch/base.hh | 38 | ||||
-rw-r--r-- | src/mem/cache/prefetch/queued.cc | 4 | ||||
-rw-r--r-- | src/mem/cache/prefetch/queued.hh | 2 |
5 files changed, 119 insertions, 8 deletions
diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py index 320755d75..316a6d0ba 100644 --- a/src/mem/cache/prefetch/Prefetcher.py +++ b/src/mem/cache/prefetch/Prefetcher.py @@ -40,13 +40,29 @@ # Mitch Hayenga from ClockedObject import ClockedObject +from m5.SimObject import * from m5.params import * from m5.proxy import * +class HWPProbeEvent(object): + def __init__(self, prefetcher, obj, *listOfNames): + self.obj = obj + self.prefetcher = prefetcher + self.names = listOfNames + + def register(self): + if self.obj: + for name in self.names: + self.prefetcher.getCCObject().addEventProbe( + self.obj.getCCObject(), name) + class BasePrefetcher(ClockedObject): type = 'BasePrefetcher' abstract = True cxx_header = "mem/cache/prefetch/base.hh" + cxx_exports = [ + PyBindMethod("addEventProbe"), + ] sys = Param.System(Parent.any, "System this prefetcher belongs to") on_miss = Param.Bool(False, "Only notify prefetcher on misses") @@ -54,6 +70,26 @@ class BasePrefetcher(ClockedObject): on_write = Param.Bool(True, "Notify prefetcher on writes") on_data = Param.Bool(True, "Notify prefetcher on data accesses") on_inst = Param.Bool(True, "Notify prefetcher on instruction accesses") + prefetch_on_access = Param.Bool(Parent.prefetch_on_access, + "Notify the hardware prefetcher on every access (not just misses)") + + _events = [] + def addEvent(self, newObject): + self._events.append(newObject) + + # Override the normal SimObject::regProbeListeners method and + # register deferred event handlers. + def regProbeListeners(self): + for event in self._events: + event.register() + self.getCCObject().regProbeListeners() + + def listenFromProbe(self, simObj, *probeNames): + if not isinstance(simObj, SimObject): + raise TypeError("argument must be of SimObject type") + if len(probeNames) <= 0: + raise TypeError("probeNames must have at least one element") + self.addEvent(HWPProbeEvent(self, simObj, *probeNames)) class QueuedPrefetcher(BasePrefetcher): type = "QueuedPrefetcher" diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index 22a12ba5f..41c02ac72 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -51,16 +51,24 @@ #include <cassert> #include "base/intmath.hh" +#include "cpu/base.hh" #include "mem/cache/base.hh" #include "params/BasePrefetcher.hh" #include "sim/system.hh" +void +BasePrefetcher::PrefetchListener::notify(const PacketPtr &pkt) +{ + parent.probeNotify(pkt); +} + BasePrefetcher::BasePrefetcher(const BasePrefetcherParams *p) - : ClockedObject(p), cache(nullptr), blkSize(0), lBlkSize(0), + : ClockedObject(p), listeners(), cache(nullptr), blkSize(0), lBlkSize(0), system(p->sys), onMiss(p->on_miss), onRead(p->on_read), onWrite(p->on_write), onData(p->on_data), onInst(p->on_inst), masterId(system->getMasterId(this)), - pageBytes(system->getPageBytes()) + pageBytes(system->getPageBytes()), + prefetchOnAccess(p->prefetch_on_access) { } @@ -163,3 +171,38 @@ BasePrefetcher::pageIthBlockAddress(Addr page, uint32_t blockIndex) const { return page + (blockIndex << lBlkSize); } + +void +BasePrefetcher::probeNotify(const PacketPtr &pkt) +{ + // Don't notify prefetcher on SWPrefetch, cache maintenance + // operations or for writes that we are coaslescing. + if (pkt->cmd.isSWPrefetch()) return; + if (pkt->req->isCacheMaintenance()) return; + if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return; + notify(pkt); +} + +void +BasePrefetcher::regProbeListeners() +{ + /** + * If no probes were added by the configuration scripts, connect to the + * parent cache using the probe "Miss". Also connect to "Hit", if the + * cache is configured to prefetch on accesses. + */ + if (listeners.empty() && cache != nullptr) { + ProbeManager *pm(cache->getProbeManager()); + listeners.push_back(new PrefetchListener(*this, pm, "Miss")); + if (prefetchOnAccess) { + listeners.push_back(new PrefetchListener(*this, pm, "Hit")); + } + } +} + +void +BasePrefetcher::addEventProbe(SimObject *obj, const char *name) +{ + ProbeManager *pm(obj->getProbeManager()); + listeners.push_back(new PrefetchListener(*this, pm, name)); +} diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index cc54ab1b8..394c85c94 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -56,6 +56,7 @@ #include "mem/packet.hh" #include "mem/request.hh" #include "sim/clocked_object.hh" +#include "sim/probe/probe.hh" class BaseCache; struct BasePrefetcherParams; @@ -63,6 +64,19 @@ class System; class BasePrefetcher : public ClockedObject { + class PrefetchListener : public ProbeListenerArgBase<PacketPtr> + { + public: + PrefetchListener(BasePrefetcher &_parent, ProbeManager *pm, + const std::string &name) + : ProbeListenerArgBase(pm, name), + parent(_parent) {} + void notify(const PacketPtr &pkt) override; + protected: + BasePrefetcher &parent; + }; + + std::vector<PrefetchListener *> listeners; protected: // PARAMETERS @@ -99,6 +113,9 @@ class BasePrefetcher : public ClockedObject const Addr pageBytes; + /** Prefetch on every access, not just misses */ + const bool prefetchOnAccess; + /** Determine if this access should be observed */ bool observeAccess(const PacketPtr &pkt) const; @@ -135,14 +152,31 @@ class BasePrefetcher : public ClockedObject /** * Notify prefetcher of cache access (may be any access or just * misses, depending on cache parameters.) - * @retval Time of next prefetch availability, or MaxTick if none. */ - virtual Tick notify(const PacketPtr &pkt) = 0; + virtual void notify(const PacketPtr &pkt) = 0; virtual PacketPtr getPacket() = 0; virtual Tick nextPrefetchReadyTime() const = 0; virtual void regStats(); + + /** + * Register probe points for this object. + */ + void regProbeListeners() override; + + /** + * Process a notification event from the ProbeListener. + * @param pkt The memory request causing the event + */ + void probeNotify(const PacketPtr &pkt); + + /** + * Add a SimObject and a probe name to listen events from + * @param obj The SimObject pointer to listen from + * @param name The probe name + */ + void addEventProbe(SimObject *obj, const char *name); }; #endif //__MEM_CACHE_PREFETCH_BASE_HH__ diff --git a/src/mem/cache/prefetch/queued.cc b/src/mem/cache/prefetch/queued.cc index 3c5647ae3..f9a036d45 100644 --- a/src/mem/cache/prefetch/queued.cc +++ b/src/mem/cache/prefetch/queued.cc @@ -63,7 +63,7 @@ QueuedPrefetcher::~QueuedPrefetcher() } } -Tick +void QueuedPrefetcher::notify(const PacketPtr &pkt) { // Verify this access type is observed by prefetcher @@ -110,8 +110,6 @@ QueuedPrefetcher::notify(const PacketPtr &pkt) } } } - - return pfq.empty() ? MaxTick : pfq.front().tick; } PacketPtr diff --git a/src/mem/cache/prefetch/queued.hh b/src/mem/cache/prefetch/queued.hh index bb38377c1..811818fdc 100644 --- a/src/mem/cache/prefetch/queued.hh +++ b/src/mem/cache/prefetch/queued.hh @@ -115,7 +115,7 @@ class QueuedPrefetcher : public BasePrefetcher QueuedPrefetcher(const QueuedPrefetcherParams *p); virtual ~QueuedPrefetcher(); - Tick notify(const PacketPtr &pkt); + void notify(const PacketPtr &pkt) override; PacketPtr insert(AddrPriority& info, bool is_secure); // Note: This should really be pure virtual, but doesnt go well with params |