mem-cache: decoupled prefetchers from cache

This patches decouples the prefetchers from the cache implementation
as the first step to allow using the classic prefetchers with ruby
caches. The prefetchers that need do cache lookups can do so using
the accessor object provided when the probes are notified. This may
also facilitate connecting the same prefetcher to multiple caches.

Related JIRA:
https://gem5.atlassian.net/browse/GEM5-457
https://gem5.atlassian.net/browse/GEM5-1112

Change-Id: I4fee1a3613ae009fabf45d7b747e4582cad315ef
Signed-off-by: Tiago Mück <tiago.muck@arm.com>
This commit is contained in:
Tiago Mück
2023-10-20 18:03:56 -05:00
parent 06bf783a85
commit af2ee0db30
34 changed files with 332 additions and 175 deletions

View File

@@ -156,7 +156,8 @@ AccessMapPatternMatching::setEntryState(AccessMapEntry &entry,
void
AccessMapPatternMatching::calculatePrefetch(const Base::PrefetchInfo &pfi,
std::vector<Queued::AddrPriority> &addresses)
std::vector<Queued::AddrPriority> &addresses,
const CacheAccessor &cache)
{
assert(addresses.empty());
@@ -262,9 +263,10 @@ AMPM::AMPM(const AMPMPrefetcherParams &p)
void
AMPM::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
ampm.calculatePrefetch(pfi, addresses);
ampm.calculatePrefetch(pfi, addresses, cache);
}
} // namespace prefetch

View File

@@ -190,7 +190,8 @@ class AccessMapPatternMatching : public ClockedObject
void startup() override;
void calculatePrefetch(const Base::PrefetchInfo &pfi,
std::vector<Queued::AddrPriority> &addresses);
std::vector<Queued::AddrPriority> &addresses,
const CacheAccessor &cache);
};
class AMPM : public Queued
@@ -201,7 +202,8 @@ class AMPM : public Queued
~AMPM() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 ARM Limited
* Copyright (c) 2013-2014, 2023 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -83,18 +83,19 @@ Base::PrefetchInfo::PrefetchInfo(PrefetchInfo const &pfi, Addr addr)
}
void
Base::PrefetchListener::notify(const PacketPtr &pkt)
Base::PrefetchListener::notify(const CacheAccessProbeArg &arg)
{
if (isFill) {
parent.notifyFill(pkt);
parent.notifyFill(arg);
} else {
parent.probeNotify(pkt, miss);
parent.probeNotify(arg, miss);
}
}
Base::Base(const BasePrefetcherParams &p)
: ClockedObject(p), listeners(), cache(nullptr), blkSize(p.block_size),
lBlkSize(floorLog2(blkSize)), onMiss(p.on_miss), onRead(p.on_read),
: ClockedObject(p), listeners(), system(nullptr), probeManager(nullptr),
blkSize(p.block_size), lBlkSize(floorLog2(blkSize)),
onMiss(p.on_miss), onRead(p.on_read),
onWrite(p.on_write), onData(p.on_data), onInst(p.on_inst),
requestorId(p.sys->getRequestorId(this)),
pageBytes(p.page_bytes),
@@ -107,13 +108,13 @@ Base::Base(const BasePrefetcherParams &p)
}
void
Base::setCache(BaseCache *_cache)
Base::setParentInfo(System *sys, ProbeManager *pm, unsigned blk_size)
{
assert(!cache);
cache = _cache;
assert(!system && !probeManager);
system = sys;
probeManager = pm;
// If the cache has a different block size from the system's, save it
blkSize = cache->getBlockSize();
blkSize = blk_size;
lBlkSize = floorLog2(blkSize);
}
@@ -157,7 +158,7 @@ Base::StatGroup::StatGroup(statistics::Group *parent)
}
bool
Base::observeAccess(const PacketPtr &pkt, bool miss) const
Base::observeAccess(const PacketPtr &pkt, bool miss, bool prefetched) const
{
bool fetch = pkt->req->isInstFetch();
bool read = pkt->isRead();
@@ -165,7 +166,7 @@ Base::observeAccess(const PacketPtr &pkt, bool miss) const
if (!miss) {
if (prefetchOnPfHit)
return hasBeenPrefetched(pkt->getAddr(), pkt->isSecure());
return prefetched;
if (!prefetchOnAccess)
return false;
}
@@ -184,24 +185,6 @@ Base::observeAccess(const PacketPtr &pkt, bool miss) const
return true;
}
bool
Base::inCache(Addr addr, bool is_secure) const
{
return cache->inCache(addr, is_secure);
}
bool
Base::inMissQueue(Addr addr, bool is_secure) const
{
return cache->inMissQueue(addr, is_secure);
}
bool
Base::hasBeenPrefetched(Addr addr, bool is_secure) const
{
return cache->hasBeenPrefetched(addr, is_secure);
}
bool
Base::samePage(Addr a, Addr b) const
{
@@ -239,18 +222,23 @@ Base::pageIthBlockAddress(Addr page, uint32_t blockIndex) const
}
void
Base::probeNotify(const PacketPtr &pkt, bool miss)
Base::probeNotify(const CacheAccessProbeArg &acc, bool miss)
{
const PacketPtr pkt = acc.pkt;
const CacheAccessor &cache = acc.cache;
// 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;
if (pkt->isWrite() && cache.coalesce()) return;
if (!pkt->req->hasPaddr()) {
panic("Request must have a physical address");
}
if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
bool has_been_prefetched =
acc.cache.hasBeenPrefetched(pkt->getAddr(), pkt->isSecure());
if (has_been_prefetched) {
usefulPrefetches += 1;
prefetchStats.pfUseful++;
if (miss)
@@ -260,13 +248,13 @@ Base::probeNotify(const PacketPtr &pkt, bool miss)
}
// Verify this access type is observed by prefetcher
if (observeAccess(pkt, miss)) {
if (observeAccess(pkt, miss, has_been_prefetched)) {
if (useVirtualAddresses && pkt->req->hasVaddr()) {
PrefetchInfo pfi(pkt, pkt->req->getVaddr(), miss);
notify(pkt, pfi);
notify(acc, pfi);
} else if (!useVirtualAddresses) {
PrefetchInfo pfi(pkt, pkt->req->getPaddr(), miss);
notify(pkt, pfi);
notify(acc, pfi);
}
}
}
@@ -279,14 +267,13 @@ Base::regProbeListeners()
* 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", false,
true));
listeners.push_back(new PrefetchListener(*this, pm, "Fill", true,
false));
listeners.push_back(new PrefetchListener(*this, pm, "Hit", false,
false));
if (listeners.empty() && probeManager != nullptr) {
listeners.push_back(new PrefetchListener(*this, probeManager,
"Miss", false, true));
listeners.push_back(new PrefetchListener(*this, probeManager,
"Fill", true, false));
listeners.push_back(new PrefetchListener(*this, probeManager,
"Hit", false, false));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 ARM Limited
* Copyright (c) 2013-2014, 2023 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -52,7 +52,7 @@
#include "base/compiler.hh"
#include "base/statistics.hh"
#include "base/types.hh"
#include "mem/cache/cache_blk.hh"
#include "mem/cache/cache_probe_arg.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
#include "sim/byteswap.hh"
@@ -62,15 +62,16 @@
namespace gem5
{
class BaseCache;
struct BasePrefetcherParams;
class ProbeManager;
class System;
namespace prefetch
{
class Base : public ClockedObject
{
class PrefetchListener : public ProbeListenerArgBase<PacketPtr>
class PrefetchListener : public ProbeListenerArgBase<CacheAccessProbeArg>
{
public:
PrefetchListener(Base &_parent, ProbeManager *pm,
@@ -78,7 +79,7 @@ class Base : public ClockedObject
bool _miss = false)
: ProbeListenerArgBase(pm, name),
parent(_parent), isFill(_isFill), miss(_miss) {}
void notify(const PacketPtr &pkt) override;
void notify(const CacheAccessProbeArg &arg) override;
protected:
Base &parent;
const bool isFill;
@@ -262,8 +263,11 @@ class Base : public ClockedObject
// PARAMETERS
/** Pointr to the parent cache. */
BaseCache* cache;
/** Pointer to the parent system. */
System* system;
/** Pointer to the parent cache's probe manager. */
ProbeManager *probeManager;
/** The block size of the parent cache. */
unsigned blkSize;
@@ -304,16 +308,9 @@ class Base : public ClockedObject
* Determine if this access should be observed
* @param pkt The memory request causing the event
* @param miss whether this event comes from a cache miss
* @param prefetched on a hit, this indicates the block was prefetched
*/
bool observeAccess(const PacketPtr &pkt, bool miss) const;
/** Determine if address is in cache */
bool inCache(Addr addr, bool is_secure) const;
/** Determine if address is in cache miss queue */
bool inMissQueue(Addr addr, bool is_secure) const;
bool hasBeenPrefetched(Addr addr, bool is_secure) const;
bool observeAccess(const PacketPtr &pkt, bool miss, bool prefetched) const;
/** Determine if addresses are on the same page */
bool samePage(Addr a, Addr b) const;
@@ -370,16 +367,18 @@ class Base : public ClockedObject
Base(const BasePrefetcherParams &p);
virtual ~Base() = default;
virtual void setCache(BaseCache *_cache);
virtual void
setParentInfo(System *sys, ProbeManager *pm, unsigned blk_size);
/**
* Notify prefetcher of cache access (may be any access or just
* misses, depending on cache parameters.)
*/
virtual void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) = 0;
virtual void
notify(const CacheAccessProbeArg &acc, const PrefetchInfo &pfi) = 0;
/** Notify prefetcher of cache fill */
virtual void notifyFill(const PacketPtr &pkt)
virtual void notifyFill(const CacheAccessProbeArg &acc)
{}
virtual PacketPtr getPacket() = 0;
@@ -423,10 +422,10 @@ class Base : public ClockedObject
/**
* Process a notification event from the ProbeListener.
* @param pkt The memory request causing the event
* @param acc probe arg encapsulating the memory request causing the event
* @param miss whether this event comes from a cache miss
*/
void probeNotify(const PacketPtr &pkt, bool miss);
void probeNotify(const CacheAccessProbeArg &acc, bool miss);
/**
* Add a SimObject and a probe name to listen events from

View File

@@ -227,7 +227,8 @@ BOP::bestOffsetLearning(Addr x)
void
BOP::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
Addr addr = pfi.getAddr();
Addr tag_x = tag(addr);
@@ -252,8 +253,10 @@ BOP::calculatePrefetch(const PrefetchInfo &pfi,
}
void
BOP::notifyFill(const PacketPtr& pkt)
BOP::notifyFill(const CacheAccessProbeArg &arg)
{
const PacketPtr& pkt = arg.pkt;
// Only insert into the RR right way if it's the pkt is a HWP
if (!pkt->cmd.isHWPrefetch()) return;

View File

@@ -148,7 +148,7 @@ class BOP : public Queued
void bestOffsetLearning(Addr);
/** Update the RR right table after a prefetch fill */
void notifyFill(const PacketPtr& pkt) override;
void notifyFill(const CacheAccessProbeArg &arg) override;
public:
@@ -156,7 +156,8 @@ class BOP : public Queued
~BOP() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -125,7 +125,8 @@ DeltaCorrelatingPredictionTables::DCPTEntry::getCandidates(
void
DeltaCorrelatingPredictionTables::calculatePrefetch(
const Base::PrefetchInfo &pfi,
std::vector<Queued::AddrPriority> &addresses)
std::vector<Queued::AddrPriority> &addresses,
const CacheAccessor &cache)
{
if (!pfi.hasPC()) {
DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
@@ -156,9 +157,10 @@ DCPT::DCPT(const DCPTPrefetcherParams &p)
void
DCPT::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
dcpt.calculatePrefetch(pfi, addresses);
dcpt.calculatePrefetch(pfi, addresses, cache);
}
} // namespace prefetch

View File

@@ -114,9 +114,11 @@ class DeltaCorrelatingPredictionTables : public SimObject
* Computes the prefetch candidates given a prefetch event.
* @param pfi The prefetch event information
* @param addresses prefetch candidates generated
* @param cache accessor for cache lookups
*/
void calculatePrefetch(const Base::PrefetchInfo &pfi,
std::vector<Queued::AddrPriority> &addresses);
std::vector<Queued::AddrPriority> &addresses,
const CacheAccessor &cache);
};
@@ -130,7 +132,8 @@ class DCPT : public Queued
~DCPT() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -56,7 +56,8 @@ IndirectMemory::IndirectMemory(const IndirectMemoryPrefetcherParams &p)
void
IndirectMemory::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
// This prefetcher requires a PC
if (!pfi.hasPC()) {

View File

@@ -201,7 +201,8 @@ class IndirectMemory : public Queued
~IndirectMemory() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -66,7 +66,8 @@ IrregularStreamBuffer::IrregularStreamBuffer(
void
IrregularStreamBuffer::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
// This prefetcher requires a PC
if (!pfi.hasPC()) {

View File

@@ -137,7 +137,8 @@ class IrregularStreamBuffer : public Queued
~IrregularStreamBuffer() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019 ARM Limited
* Copyright (c) 2014, 2019, 2023 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -53,10 +53,10 @@ Multi::Multi(const MultiPrefetcherParams &p)
}
void
Multi::setCache(BaseCache *_cache)
Multi::setParentInfo(System *sys, ProbeManager *pm, unsigned blk_size)
{
for (auto pf : prefetchers)
pf->setCache(_cache);
pf->setParentInfo(sys, pm, blk_size);
}
Tick

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019 ARM Limited
* Copyright (c) 2014, 2019, 2023 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -56,7 +56,8 @@ class Multi : public Base
Multi(const MultiPrefetcherParams &p);
public:
void setCache(BaseCache *_cache) override;
void
setParentInfo(System *sys, ProbeManager *pm, unsigned blk_size) override;
PacketPtr getPacket() override;
Tick nextPrefetchReadyTime() const override;
@@ -65,8 +66,11 @@ class Multi : public Base
* Ignore notifications since each sub-prefetcher already gets a
* notification through their probes-based interface.
*/
void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) override {};
void notifyFill(const PacketPtr &pkt) override {};
void
notify(const CacheAccessProbeArg &arg, const PrefetchInfo &pfi) override
{};
void notifyFill(const CacheAccessProbeArg &arg) override {};
/** @} */
protected:

View File

@@ -198,7 +198,8 @@ PIF::notifyRetiredInst(const Addr pc)
void
PIF::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
if (!pfi.hasPC()) {
return;

View File

@@ -182,7 +182,8 @@ class PIF : public Queued
~PIF() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses);
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache);
/**
* Add a SimObject and a probe name to monitor the retired instructions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2015 ARM Limited
* Copyright (c) 2014-2015, 2023 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -94,7 +94,7 @@ Queued::DeferredPacket::finish(const Fault &fault,
assert(ongoingTranslation);
ongoingTranslation = false;
bool failed = (fault != NoFault);
owner->translationComplete(this, failed);
owner->translationComplete(this, failed, *cache);
}
Queued::Queued(const QueuedPrefetcherParams &p)
@@ -169,10 +169,12 @@ Queued::getMaxPermittedPrefetches(size_t total) const
}
void
Queued::notify(const PacketPtr &pkt, const PrefetchInfo &pfi)
Queued::notify(const CacheAccessProbeArg &acc, const PrefetchInfo &pfi)
{
Addr blk_addr = blockAddress(pfi.getAddr());
bool is_secure = pfi.isSecure();
const PacketPtr pkt = acc.pkt;
const CacheAccessor &cache = acc.cache;
// Squash queued prefetches if demand miss to same line
if (queueSquash) {
@@ -195,7 +197,7 @@ Queued::notify(const PacketPtr &pkt, const PrefetchInfo &pfi)
// Calculate prefetches given this access
std::vector<AddrPriority> addresses;
calculatePrefetch(pfi, addresses);
calculatePrefetch(pfi, addresses, cache);
// Get the maximu number of prefetches that we are allowed to generate
size_t max_pfs = getMaxPermittedPrefetches(addresses.size());
@@ -210,7 +212,7 @@ Queued::notify(const PacketPtr &pkt, const PrefetchInfo &pfi)
if (!samePage(addr_prio.first, pfi.getAddr())) {
statsQueued.pfSpanPage += 1;
if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
if (cache.hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
statsQueued.pfUsefulSpanPage += 1;
}
}
@@ -222,7 +224,7 @@ Queued::notify(const PacketPtr &pkt, const PrefetchInfo &pfi)
DPRINTF(HWPrefetch, "Found a pf candidate addr: %#x, "
"inserting into prefetch queue.\n", new_pfi.getAddr());
// Create and insert the request
insert(pkt, new_pfi, addr_prio.second);
insert(pkt, new_pfi, addr_prio.second, cache);
num_pfs += 1;
if (num_pfs == max_pfs) {
break;
@@ -298,7 +300,8 @@ Queued::processMissingTranslations(unsigned max)
}
void
Queued::translationComplete(DeferredPacket *dp, bool failed)
Queued::translationComplete(DeferredPacket *dp, bool failed,
const CacheAccessor &cache)
{
auto it = pfqMissingTranslation.begin();
while (it != pfqMissingTranslation.end()) {
@@ -315,8 +318,9 @@ Queued::translationComplete(DeferredPacket *dp, bool failed)
it->translationRequest->getPaddr());
Addr target_paddr = it->translationRequest->getPaddr();
// check if this prefetch is already redundant
if (cacheSnoop && (inCache(target_paddr, it->pfInfo.isSecure()) ||
inMissQueue(target_paddr, it->pfInfo.isSecure()))) {
if (cacheSnoop &&
(cache.inCache(target_paddr, it->pfInfo.isSecure()) ||
cache.inMissQueue(target_paddr, it->pfInfo.isSecure()))) {
statsQueued.pfInCache++;
DPRINTF(HWPrefetch, "Dropping redundant in "
"cache/MSHR prefetch addr:%#x\n", target_paddr);
@@ -382,7 +386,7 @@ Queued::createPrefetchRequest(Addr addr, PrefetchInfo const &pfi,
void
Queued::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
int32_t priority)
int32_t priority, const CacheAccessor &cache)
{
if (queueFilter) {
if (alreadyInQueue(pfq, new_pfi, priority)) {
@@ -451,8 +455,8 @@ Queued::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
}
}
if (has_target_pa && cacheSnoop &&
(inCache(target_paddr, new_pfi.isSecure()) ||
inMissQueue(target_paddr, new_pfi.isSecure()))) {
(cache.inCache(target_paddr, new_pfi.isSecure()) ||
cache.inMissQueue(target_paddr, new_pfi.isSecure()))) {
statsQueued.pfInCache++;
DPRINTF(HWPrefetch, "Dropping redundant in "
"cache/MSHR prefetch addr:%#x\n", target_paddr);
@@ -460,7 +464,7 @@ Queued::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
}
/* Create the packet and find the spot to insert it */
DeferredPacket dpp(this, new_pfi, 0, priority);
DeferredPacket dpp(this, new_pfi, 0, priority, cache);
if (has_target_pa) {
Tick pf_time = curTick() + clockPeriod() * latency;
dpp.createPkt(target_paddr, blkSize, requestorId, tagPrefetch,
@@ -472,7 +476,7 @@ Queued::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
} else {
// Add the translation request and try to resolve it later
dpp.setTranslationRequest(translation_req);
dpp.tc = cache->system->threads[translation_req->contextId()];
dpp.tc = system->threads[translation_req->contextId()];
DPRINTF(HWPrefetch, "Prefetch queued with no translation. "
"addr:%#x priority: %3d\n", new_pfi.getAddr(), priority);
addToQueue(pfqMissingTranslation, dpp);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2015 ARM Limited
* Copyright (c) 2014-2015, 2023 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -75,6 +75,7 @@ class Queued : public Base
RequestPtr translationRequest;
ThreadContext *tc;
bool ongoingTranslation;
const CacheAccessor *cache;
/**
* Constructor
@@ -85,9 +86,10 @@ class Queued : public Base
* @param prio This prefetch priority
*/
DeferredPacket(Queued *o, PrefetchInfo const &pfi, Tick t,
int32_t prio) : owner(o), pfInfo(pfi), tick(t), pkt(nullptr),
int32_t prio, const CacheAccessor &_cache)
: owner(o), pfInfo(pfi), tick(t), pkt(nullptr),
priority(prio), translationRequest(), tc(nullptr),
ongoingTranslation(false) {
ongoingTranslation(false), cache(&_cache) {
}
bool operator>(const DeferredPacket& that) const
@@ -192,12 +194,15 @@ class Queued : public Base
Queued(const QueuedPrefetcherParams &p);
virtual ~Queued();
void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) override;
void
notify(const CacheAccessProbeArg &acc, const PrefetchInfo &pfi) override;
void insert(const PacketPtr &pkt, PrefetchInfo &new_pfi, int32_t priority);
void insert(const PacketPtr &pkt, PrefetchInfo &new_pfi, int32_t priority,
const CacheAccessor &cache);
virtual void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) = 0;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) = 0;
PacketPtr getPacket() override;
Tick nextPrefetchReadyTime() const override
@@ -231,8 +236,10 @@ class Queued : public Base
* new prefetch request.
* @param dp the deferred packet that has completed the translation request
* @param failed whether the translation was successful
* @param cache accessor for lookups on the cache that originated this pkt
*/
void translationComplete(DeferredPacket *dp, bool failed);
void translationComplete(DeferredPacket *dp, bool failed,
const CacheAccessor &cache);
/**
* Checks whether the specified prefetch request is already in the

View File

@@ -91,8 +91,10 @@ SBOOE::access(Addr access_line)
}
void
SBOOE::notifyFill(const PacketPtr& pkt)
SBOOE::notifyFill(const CacheAccessProbeArg &arg)
{
const PacketPtr& pkt = arg.pkt;
// (1) Look for the address in the demands list
// (2) Calculate the elapsed cycles until it was filled (curTick)
// (3) Insert the latency into the latency buffer (FIFO)
@@ -117,7 +119,8 @@ SBOOE::notifyFill(const PacketPtr& pkt)
void
SBOOE::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
const Addr pfi_addr = pfi.getAddr();
const Addr pfi_line = pfi_addr >> lBlkSize;

View File

@@ -153,13 +153,14 @@ class SBOOE : public Queued
bool access(Addr line);
/** Update the latency buffer after a prefetch fill */
void notifyFill(const PacketPtr& pkt) override;
void notifyFill(const CacheAccessProbeArg &arg) override;
public:
SBOOE(const SBOOEPrefetcherParams &p);
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -227,7 +227,8 @@ SignaturePath::calculateLookaheadConfidence(PatternEntry const &sig,
void
SignaturePath::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
Addr request_addr = pfi.getAddr();
Addr ppn = request_addr / pageBytes;

View File

@@ -287,7 +287,8 @@ class SignaturePath : public Queued
~SignaturePath() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -43,11 +43,12 @@ SlimAMPM::SlimAMPM(const SlimAMPMPrefetcherParams &p)
void
SlimAMPM::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
dcpt.calculatePrefetch(pfi, addresses);
dcpt.calculatePrefetch(pfi, addresses, cache);
if (addresses.empty()) {
ampm.calculatePrefetch(pfi, addresses);
ampm.calculatePrefetch(pfi, addresses, cache);
}
}

View File

@@ -62,7 +62,8 @@ class SlimAMPM : public Queued
~SlimAMPM() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -63,7 +63,7 @@ STeMS::STeMS(const STeMSPrefetcherParams &p)
}
void
STeMS::checkForActiveGenerationsEnd()
STeMS::checkForActiveGenerationsEnd(const CacheAccessor &cache)
{
// This prefetcher operates attached to the L1 and it observes all
// accesses, this guarantees that no evictions are missed
@@ -79,8 +79,8 @@ STeMS::checkForActiveGenerationsEnd()
if (seq_entry.counter > 0) {
Addr cache_addr =
agt_entry.paddress + seq_entry.offset * blkSize;
if (!inCache(cache_addr, sr_is_secure) &&
!inMissQueue(cache_addr, sr_is_secure)) {
if (!cache.inCache(cache_addr, sr_is_secure) &&
!cache.inMissQueue(cache_addr, sr_is_secure)) {
generation_ended = true;
pst_addr = (agt_entry.pc << spatialRegionSizeBits)
+ seq_entry.offset;
@@ -135,7 +135,8 @@ STeMS::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
void
STeMS::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
if (!pfi.hasPC()) {
DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
@@ -152,7 +153,7 @@ STeMS::calculatePrefetch(const PrefetchInfo &pfi,
Addr sr_offset = (pfi.getAddr() % spatialRegionSize) / blkSize;
// Check if any active generation has ended
checkForActiveGenerationsEnd();
checkForActiveGenerationsEnd(cache);
ActiveGenerationTableEntry *agt_entry =
activeGenerationTable.findEntry(sr_addr, is_secure);

View File

@@ -181,7 +181,7 @@ class STeMS : public Queued
unsigned int lastTriggerCounter;
/** Checks if the active generations have ended */
void checkForActiveGenerationsEnd();
void checkForActiveGenerationsEnd(const CacheAccessor &cache);
/**
* Adds an entry to the RMOB
* @param sr_addr Spatial region address
@@ -206,7 +206,8 @@ class STeMS : public Queued
~STeMS() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -118,7 +118,8 @@ Stride::allocateNewContext(int context)
void
Stride::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
if (!pfi.hasPC()) {
DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");

View File

@@ -160,7 +160,8 @@ class Stride : public Queued
Stride(const StridePrefetcherParams &p);
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch

View File

@@ -49,7 +49,8 @@ Tagged::Tagged(const TaggedPrefetcherParams &p)
void
Tagged::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache)
{
Addr blkAddr = blockAddress(pfi.getAddr());

View File

@@ -55,7 +55,8 @@ class Tagged : public Queued
~Tagged() = default;
void calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses) override;
std::vector<AddrPriority> &addresses,
const CacheAccessor &cache) override;
};
} // namespace prefetch