45#include "debug/HWPrefetch.hh"
46#include "debug/HWPrefetchQueue.hh"
49#include "params/QueuedPrefetcher.hh"
63 RequestPtr req = std::make_shared<Request>(paddr, blk_size,
82 assert(translationRequest !=
nullptr);
83 if (!ongoingTranslation) {
84 ongoingTranslation =
true;
94 assert(ongoingTranslation);
95 ongoingTranslation =
false;
96 bool failed = (fault !=
NoFault);
97 owner->translationComplete(
this, failed, *cache);
103 p.max_prefetch_requests_with_pending_translation),
123 std::string queue_name =
"";
124 if (&queue == &
pfq) {
128 queue_name =
"PFTransQ";
135 Addr paddr = it->pkt ? it->pkt->getAddr() : 0;
136 DPRINTF(HWPrefetchQueue,
"%s[%d]: Prefetch Req VA: %#x PA: %#x "
137 "prio: %3d\n", queue_name, pos,
vaddr, paddr, it->priority);
160 size_t max_pfs =
total;
163 size_t min_pfs = (
total - throttle_pfs) == 0 ?
164 1 : (
total - throttle_pfs);
165 max_pfs = min_pfs + (
total - min_pfs) *
181 auto itr =
pfq.begin();
182 while (itr !=
pfq.end()) {
184 itr->pfInfo.isSecure() == is_secure) {
185 DPRINTF(HWPrefetch,
"Removing pf candidate addr: %#x "
186 "(cl: %#x), demand request going to the same addr\n",
187 itr->pfInfo.getAddr(),
190 itr =
pfq.erase(itr);
220 bool can_cross_page = (
mmu !=
nullptr);
224 DPRINTF(HWPrefetch,
"Found a pf candidate addr: %#x, "
225 "inserting into prefetch queue.\n", new_pfi.
getAddr());
227 insert(pkt, new_pfi, addr_prio.second, cache);
229 if (num_pfs == max_pfs) {
233 DPRINTF(HWPrefetch,
"Ignoring page crossing prefetch.\n");
241 DPRINTF(HWPrefetch,
"Requesting a prefetch to issue.\n");
250 DPRINTF(HWPrefetch,
"No hardware prefetches available.\n");
259 assert(pkt !=
nullptr);
260 DPRINTF(HWPrefetch,
"Generating prefetch for %#x.\n", pkt->
getAddr());
267 : statistics::
Group(parent),
268 ADD_STAT(pfIdentified, statistics::units::Count::get(),
269 "number of prefetch candidates identified"),
270 ADD_STAT(pfBufferHit, statistics::units::Count::get(),
271 "number of redundant prefetches already in prefetch queue"),
272 ADD_STAT(pfInCache, statistics::units::Count::get(),
273 "number of redundant prefetches already in cache/mshr dropped"),
274 ADD_STAT(pfRemovedDemand, statistics::units::Count::get(),
275 "number of prefetches dropped due to a demand for the same "
277 ADD_STAT(pfRemovedFull, statistics::units::Count::get(),
278 "number of prefetches dropped due to prefetch queue size"),
279 ADD_STAT(pfSpanPage, statistics::units::Count::get(),
280 "number of prefetches that crossed the page"),
281 ADD_STAT(pfUsefulSpanPage, statistics::units::Count::get(),
282 "number of prefetches that is useful and crossed the page")
315 DPRINTF(HWPrefetch,
"%s Translation of vaddr %#x succeeded: "
317 it->translationRequest->getVaddr(),
318 it->translationRequest->getPaddr());
319 Addr target_paddr = it->translationRequest->getPaddr();
322 (cache.
inCache(target_paddr, it->pfInfo.isSecure()) ||
323 cache.
inMissQueue(target_paddr, it->pfInfo.isSecure()))) {
325 DPRINTF(HWPrefetch,
"Dropping redundant in "
326 "cache/MSHR prefetch addr:%#x\n", target_paddr);
334 DPRINTF(HWPrefetch,
"%s Translation of vaddr %#x failed, dropping "
335 "prefetch request %#x \n",
mmu->
name(),
336 it->translationRequest->getVaddr());
347 for (it = queue.begin(); it != queue.end() && !found; it++) {
348 found = it->pfInfo.sameAddr(pfi);
352 if (it != queue.end()) {
358 while (prev != queue.begin()) {
362 std::swap(*it, *prev);
366 DPRINTF(HWPrefetch,
"Prefetch addr already in "
367 "prefetch queue, priority updated\n");
369 DPRINTF(HWPrefetch,
"Prefetch addr already in "
380 RequestPtr translation_req = std::make_shared<Request>(
382 pkt->
req->contextId());
384 return translation_req;
413 pkt->
req->getVaddr() : pkt->
req->getPaddr();
414 bool positive_stride = new_pfi.
getAddr() >= orig_addr;
416 (new_pfi.
getAddr() - orig_addr) : (orig_addr - new_pfi.
getAddr());
419 bool has_target_pa =
false;
426 target_paddr = positive_stride ? (pkt->
req->getPaddr() +
stride) :
429 target_paddr = new_pfi.
getAddr();
431 has_target_pa =
true;
436 if (!pkt->
req->hasContextId()) {
440 has_target_pa =
false;
443 }
else if (pkt->
req->hasVaddr()) {
444 has_target_pa =
false;
446 Addr target_vaddr = positive_stride ?
461 DPRINTF(HWPrefetch,
"Dropping redundant in "
462 "cache/MSHR prefetch addr:%#x\n", target_paddr);
472 DPRINTF(HWPrefetch,
"Prefetch queued. "
473 "addr:%#x priority: %3d tick:%lld.\n",
480 DPRINTF(HWPrefetch,
"Prefetch queued with no translation. "
496 "Prefetch queue is both full and empty!");
500 "Prefetch queue is full with 1 element!");
504 while (cont && prev != queue.begin()) {
507 cont = prev->priority == it->priority;
512 DPRINTF(HWPrefetch,
"Prefetch queue full, removing lowest priority "
513 "oldest packet, addr: %#x\n",it->pfInfo.getAddr());
518 if ((queue.size() == 0) || (dpp <= queue.back())) {
519 queue.emplace_back(dpp);
524 }
while (it != queue.begin() && dpp > *it);
527 if (it == queue.begin() && dpp <= *it)
529 queue.insert(it, dpp);
532 if (debug::HWPrefetchQueue)
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
Information provided to probes on a cache event.
PacketPtr pkt
Packet that triggered the cache access.
CacheAccessor & cache
Accessor for the cache.
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
RequestPtr req
A pointer to the original request.
void allocate()
Allocate memory for the packet.
@ SECURE
The request targets the secure memory space.
@ PREFETCH
The request is a prefetch.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Addr getPC() const
Returns the program counter that generated this request.
bool isSecure() const
Returns true if the address targets the secure memory space.
Addr getAddr() const
Obtains the address value of this Prefetcher address.
bool hasPC() const
Returns true if the associated program counter is valid.
const bool useVirtualAddresses
Use Virtual Addresses for prefetching.
unsigned blkSize
The block size of the parent cache.
uint64_t issuedPrefetches
Total prefetches issued.
const RequestorID requestorId
Request id for prefetches.
uint64_t usefulPrefetches
Total prefetches that has been useful.
gem5::prefetch::Base::StatGroup prefetchStats
BaseMMU * mmu
Registered mmu for address translations.
System * system
Pointer to the parent system.
Addr blockAddress(Addr a) const
Determine the address of the block in which a lays.
bool samePage(Addr a, Addr b) const
Determine if addresses are on the same page.
void translationComplete(DeferredPacket *dp, bool failed, const CacheAccessor &cache)
Indicates that the translation of the address of the provided deferred packet has been successfully c...
const bool queueSquash
Squash queued prefetch if demand access observed.
gem5::prefetch::Queued::QueuedStats statsQueued
void insert(const PacketPtr &pkt, PrefetchInfo &new_pfi, int32_t priority, const CacheAccessor &cache)
std::list< DeferredPacket >::iterator iterator
void notify(const CacheAccessProbeArg &acc, const PrefetchInfo &pfi) override
Notify prefetcher of cache access (may be any access or just misses, depending on cache parameters....
Queued(const QueuedPrefetcherParams &p)
void printQueue(const std::list< DeferredPacket > &queue) const
const unsigned queueSize
Maximum size of the prefetch queue.
std::list< DeferredPacket > pfqMissingTranslation
void processMissingTranslations(unsigned max)
Starts the translations of the queued prefetches with a missing translation.
RequestPtr createPrefetchRequest(Addr addr, PrefetchInfo const &pfi, PacketPtr pkt)
const bool queueFilter
Filter prefetches if already queued.
std::list< DeferredPacket >::const_iterator const_iterator
virtual void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses, const CacheAccessor &cache)=0
const bool tagPrefetch
Tag prefetch with PC of generating access?
const Cycles latency
Cycles after generation when a prefetch can first be issued.
const bool cacheSnoop
Snoop the cache before generating prefetch (cheating basically)
const unsigned int throttleControlPct
Percentage of requests that can be throttled.
PacketPtr getPacket() override
void addToQueue(std::list< DeferredPacket > &queue, DeferredPacket &dpp)
Adds a DeferredPacket to the specified queue.
bool alreadyInQueue(std::list< DeferredPacket > &queue, const PrefetchInfo &pfi, int32_t priority)
Checks whether the specified prefetch request is already in the specified queue.
size_t getMaxPermittedPrefetches(size_t total) const
Returns the maxmimum number of prefetch requests that are allowed to be created from the number of pr...
const unsigned missingTranslationQueueSize
Maximum size of the queue holding prefetch requests with missing address translations.
std::list< DeferredPacket > pfq
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Declares a basic cache interface BaseCache.
Bitfield< 21, 20 > stride
Bitfield< 3, 0 > priority
const FlagsType total
Print the total.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
std::shared_ptr< Request > RequestPtr
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
constexpr decltype(nullptr) NoFault
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
Provides generic cache lookup functions.
virtual bool inCache(Addr addr, bool is_secure) const =0
Determine if address is in cache.
virtual bool inMissQueue(Addr addr, bool is_secure) const =0
Determine if address is in cache miss queue.
virtual bool hasBeenPrefetched(Addr addr, bool is_secure) const =0
Determine if address has been prefetched.
statistics::Scalar pfIssued
Tick tick
Time when this prefetch becomes ready.
void startTranslation(BaseMMU *mmu)
Issues the translation request to the provided MMU.
void setTranslationRequest(const RequestPtr &req)
Sets the translation request needed to obtain the physical address of this request.
void createPkt(Addr paddr, unsigned blk_size, RequestorID requestor_id, bool tag_prefetch, Tick t)
Create the associated memory packet.
void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) override
PacketPtr pkt
The memory packet generated by this prefetch.
PrefetchInfo pfInfo
Prefetch info corresponding to this packet.
statistics::Scalar pfUsefulSpanPage
statistics::Scalar pfBufferHit
statistics::Scalar pfIdentified
statistics::Scalar pfRemovedDemand
statistics::Scalar pfRemovedFull
statistics::Scalar pfSpanPage
statistics::Scalar pfInCache
QueuedStats(statistics::Group *parent)