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>
This commit is contained in:
committed by
Javier Bueno Hedo
parent
e8e92a12af
commit
8590243fef
36
src/mem/cache/prefetch/Prefetcher.py
vendored
36
src/mem/cache/prefetch/Prefetcher.py
vendored
@@ -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"
|
||||
|
||||
47
src/mem/cache/prefetch/base.cc
vendored
47
src/mem/cache/prefetch/base.cc
vendored
@@ -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));
|
||||
}
|
||||
|
||||
38
src/mem/cache/prefetch/base.hh
vendored
38
src/mem/cache/prefetch/base.hh
vendored
@@ -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__
|
||||
|
||||
4
src/mem/cache/prefetch/queued.cc
vendored
4
src/mem/cache/prefetch/queued.cc
vendored
@@ -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
|
||||
|
||||
2
src/mem/cache/prefetch/queued.hh
vendored
2
src/mem/cache/prefetch/queued.hh
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user