Discussion:
[gem5-dev] Change in gem5/gem5[master]: mem-cache: Support for page crossing prefetches
(too old to reply)
Javier Bueno Hedo (Gerrit)
2018-11-28 14:28:53 UTC
Permalink
Hello Giacomo Travaglini, Andreas Sandberg,

I'd like you to do a code review. Please visit

https://gem5-review.googlesource.com/c/public/gem5/+/14620

to review the following change.


Change subject: mem-cache: Support for page crossing prefetches
......................................................................

mem-cache: Support for page crossing prefetches

Prefetchers can now issue hardware prefetch requests that go beyond
the boundaries of the system page. Page crossing references will need
to look up the TLBs to be able to compute the physical address to be
prefetched.

Change-Id: Ib56374097e3b7dc87414139d210ea9272f96b06b
---
M src/mem/cache/prefetch/Prefetcher.py
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/cache/prefetch/queued.cc
M src/mem/cache/prefetch/queued.hh
M src/mem/cache/prefetch/stride.cc
M src/mem/cache/prefetch/tagged.cc
7 files changed, 329 insertions(+), 129 deletions(-)



diff --git a/src/mem/cache/prefetch/Prefetcher.py
b/src/mem/cache/prefetch/Prefetcher.py
index df547ed..cbc3b76 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -78,6 +78,7 @@
"Notify the hardware prefetcher on every access (not just misses)")
use_virtual_addresses = Param.Bool(False,
"Use virtual addresses for prefetching")
+ page_crossing = Param.Bool(False, "Allow page crossing prefetches")

_events = []
def addEvent(self, newObject):
@@ -104,6 +105,8 @@
cxx_header = "mem/cache/prefetch/queued.hh"
latency = Param.Int(1, "Latency for generated prefetches")
queue_size = Param.Int(32, "Maximum number of queued prefetches")
+ missing_translation_queue_size = Param.Int(32,
+ "Maximum number of queued prefetches that have a missing
translation")
queue_squash = Param.Bool(True, "Squash queued prefetch on demand
access")
queue_filter = Param.Bool(True, "Don't queue redundant prefetches")
cache_snoop = Param.Bool(False, "Snoop cache to eliminate redundant
request")
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index e58d4f3..50007f6 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -81,7 +81,8 @@
onWrite(p->on_write), onData(p->on_data), onInst(p->on_inst),
masterId(p->sys->getMasterId(this)),
pageBytes(p->sys->getPageBytes()),
prefetchOnAccess(p->prefetch_on_access),
- useVirtualAddresses(p->use_virtual_addresses)
+ useVirtualAddresses(p->use_virtual_addresses),
+ pageCrossing(p->page_crossing)
{
}

diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 6f1e35b..7e270ec 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -205,6 +205,9 @@
/** Use Virtual Addresses for prefetching */
const bool useVirtualAddresses;

+ /** Allow page crossing prefetches */
+ const bool pageCrossing;
+
/** Determine if this access should be observed */
bool observeAccess(const PacketPtr &pkt) const;

diff --git a/src/mem/cache/prefetch/queued.cc
b/src/mem/cache/prefetch/queued.cc
index d3099e6..c284b18 100644
--- a/src/mem/cache/prefetch/queued.cc
+++ b/src/mem/cache/prefetch/queued.cc
@@ -41,16 +41,42 @@

#include <cassert>

+#include "arch/generic/tlb.hh"
#include "base/logging.hh"
#include "base/trace.hh"
#include "debug/HWPrefetch.hh"
+#include "mem/cache/base.hh"
#include "mem/request.hh"
#include "params/QueuedPrefetcher.hh"
+#include "sim/faults.hh"
+
+
+void
+QueuedPrefetcher::DeferredPacket::createPkt(Addr paddr, unsigned blk_size,
+ MasterID mid, bool
tag_prefetch,
+ Tick t) {
+ /* Create a prefetch memory request */
+ RequestPtr req = std::make_shared<Request>(paddr, blk_size, 0, mid);
+
+ if (pfInfo.isSecure()) {
+ req->setFlags(Request::SECURE);
+ }
+ req->taskId(ContextSwitchTaskId::Prefetcher);
+ pkt = new Packet(req, MemCmd::HardPFReq);
+ pkt->allocate();
+ if (tag_prefetch && pfInfo.hasPC()) {
+ // Tag prefetch packet with accessing pc
+ pkt->req->setPC(pfInfo.getPC());
+ }
+ tick = t;
+}

QueuedPrefetcher::QueuedPrefetcher(const QueuedPrefetcherParams *p)
- : BasePrefetcher(p), queueSize(p->queue_size), latency(p->latency),
- queueSquash(p->queue_squash), queueFilter(p->queue_filter),
- cacheSnoop(p->cache_snoop), tagPrefetch(p->tag_prefetch)
+ : BasePrefetcher(p), queueSize(p->queue_size),
+ missingTranslationQueueSize(p->missing_translation_queue_size),
+ latency(p->latency), queueSquash(p->queue_squash),
+ queueFilter(p->queue_filter), cacheSnoop(p->cache_snoop),
+ tagPrefetch(p->tag_prefetch)
{

}
@@ -93,14 +119,20 @@
// Block align prefetch address
addr_prio.first = blockAddress(addr_prio.first);

- PrefetchInfo new_pfi(pfi,addr_prio.first);
+ if (!samePage(addr_prio.first, pfi.getAddr())) {
+ pfSpanPage += 1;
+ }

- pfIdentified++;
- 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);
+ if (pageCrossing or samePage(addr_prio.first, pfi.getAddr())) {
+ PrefetchInfo new_pfi(pfi,addr_prio.first);
+ pfIdentified++;
+ 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);
+ } else {
+ DPRINTF(HWPrefetch, "Ignoring page crossing prefetch.\n");
+ }
}
}

@@ -110,6 +142,12 @@
DPRINTF(HWPrefetch, "Requesting a prefetch to issue.\n");

if (pfq.empty()) {
+ // If the queue is empty, attempt first to fill it with requests
+ // from the queue of missing translations
+ attemptMissingTranslations(queueSize);
+ }
+
+ if (pfq.empty()) {
DPRINTF(HWPrefetch, "No hardware prefetches available.\n");
return nullptr;
}
@@ -120,29 +158,11 @@
pfIssued++;
assert(pkt != nullptr);
DPRINTF(HWPrefetch, "Generating prefetch for %#x.\n", pkt->getAddr());
+
+ attemptMissingTranslations(queueSize - pfq.size());
return pkt;
}

-QueuedPrefetcher::const_iterator
-QueuedPrefetcher::inPrefetch(const PrefetchInfo &pfi) const
-{
- for (const_iterator dp = pfq.begin(); dp != pfq.end(); dp++) {
- if (dp->pfInfo.sameAddr(pfi)) return dp;
- }
-
- return pfq.end();
-}
-
-QueuedPrefetcher::iterator
-QueuedPrefetcher::inPrefetch(const PrefetchInfo &pfi)
-{
- for (iterator dp = pfq.begin(); dp != pfq.end(); dp++) {
- if (dp->pfInfo.sameAddr(pfi)) return dp;
- }
-
- return pfq.end();
-}
-
void
QueuedPrefetcher::regStats()
{
@@ -169,89 +189,220 @@
.desc("number of prefetches not generated due to page crossing");
}

+bool
+QueuedPrefetcher::translateVirtualAddress(const RequestPtr &req) const {
+ bool done = false;
+ for (unsigned cidx = 0;
+ cidx < cache->system->numContexts() && !done;
+ cidx += 1)
+ {
+ ThreadContext *tc = cache->system->getThreadContext(cidx);
+ Fault f = tc->getDTBPtr()->translateFunctional(req, tc,
BaseTLB::Read);
+ if (f == NoFault) {
+ done = true;
+ DPRINTF(HWPrefetch, "Translation of vaddr %#x succeeded: "
+ "paddr %#x \n", req->getVaddr(), req->getPaddr());
+ } else {
+ DPRINTF(HWPrefetch, "Translation of vaddr %#x failed\n",
+ req->getVaddr());
+ }
+ }
+ return done;
+}
+
+void
+QueuedPrefetcher::attemptMissingTranslations(unsigned max) {
+ unsigned count = 0;
+ iterator it = pfqMissingTranslation.begin();
+ while (it != pfqMissingTranslation.end() && count < max) {
+ if (translateVirtualAddress(it->translationRequest)) {
+ 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()))) {
+ pfInCache++;
+ DPRINTF(HWPrefetch, "Dropping redundant in "
+ "cache/MSHR prefetch addr:%#x\n", target_paddr);
+ } else {
+ Tick pf_time = curTick() + clockPeriod() * latency;
+ it->createPkt(it->translationRequest->getPaddr(), blkSize,
+ masterId, tagPrefetch, pf_time);
+ addToQueue(pfq, *it);
+ count += 1;
+ }
+ it = pfqMissingTranslation.erase(it);
+ } else {
+ it++;
+ }
+ }
+}
+
+bool
+QueuedPrefetcher::alreadyInQueue(std::list<DeferredPacket> &queue,
+ const PrefetchInfo &pfi, int32_t priority)
+{
+ bool found = false;
+ iterator it;
+ for (it = queue.begin(); it != queue.end() && !found; it++) {
+ found = it->pfInfo.sameAddr(pfi);
+ }
+
+ /* If the address is already in the queue, update priority and leave */
+ if (it != queue.end()) {
+ pfBufferHit++;
+ if (it->priority < priority) {
+ /* Update priority value and position in the queue */
+ it->priority = priority;
+ iterator prev = it;
+ bool cont = true;
+ while (cont && prev != queue.begin()) {
+ prev--;
+ /* If the packet has higher priority, swap */
+ if (*it > *prev) {
+ std::swap(*it, *prev);
+ it = prev;
+ }
+ }
+ DPRINTF(HWPrefetch, "Prefetch addr already in "
+ "prefetch queue, priority updated\n");
+ } else {
+ DPRINTF(HWPrefetch, "Prefetch addr already in "
+ "prefetch queue\n");
+ }
+ }
+ return found;
+}
+
void
QueuedPrefetcher::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
int32_t priority)
{
if (queueFilter) {
- iterator it = inPrefetch(new_pfi);
- /* If the address is already in the queue, update priority and
leave */
- if (it != pfq.end()) {
- pfBufferHit++;
- if (it->priority < priority) {
- /* Update priority value and position in the queue */
- it->priority = priority;
- iterator prev = it;
- bool cont = true;
- while (cont && prev != pfq.begin()) {
- prev--;
- /* If the packet has higher priority, swap */
- if (*it > *prev) {
- std::swap(*it, *prev);
- it = prev;
- }
- }
- DPRINTF(HWPrefetch, "Prefetch addr already in "
- "prefetch queue, priority updated\n");
- } else {
- DPRINTF(HWPrefetch, "Prefetch addr already in "
- "prefetch queue\n");
- }
+ if (alreadyInQueue(pfq, new_pfi, priority)) {
+ return;
+ }
+ if (alreadyInQueue(pfqMissingTranslation, new_pfi, priority)) {
return;
}
}

- Addr target_addr = new_pfi.getAddr();
- if (useVirtualAddresses) {
- assert(pkt->req->hasPaddr());
- //if we trained with virtual addresses, compute the phsysical
address
- if (new_pfi.getAddr() >= pkt->req->getVaddr()) {
- //positive stride
- target_addr = pkt->req->hasPaddr() +
- (new_pfi.getAddr() - pkt->req->getVaddr());
+ /*
+ * Physical address computation
+ * if the prefetch is within the same page
+ * using VA: add the computed stride to the original PA
+ * using PA: no actions needed
+ * if we are page crossing
+ * using VA: attempt to translate the address
+ * using PA: use the provided VA to obtain the target VA, then
+ * attempt to translate the resulting address
+ *
+ * if a translation fails, enqueue the prefetch request in the missing
+ * translation queue, and attempt to translate later
+ */
+
+ Addr orig_addr = useVirtualAddresses ?
+ pkt->req->getVaddr() : pkt->req->getPaddr();
+ bool positive_stride = new_pfi.getAddr() >= orig_addr;
+ Addr stride = positive_stride ?
+ (new_pfi.getAddr() - orig_addr) : (orig_addr - new_pfi.getAddr());
+
+ Addr target_paddr;
+ bool has_target_pa = false;
+ RequestPtr translation_req = nullptr;
+ if (samePage(orig_addr, new_pfi.getAddr())) {
+ if (useVirtualAddresses) {
+ // if we trained with virtual addresses,
+ // compute the phsysical address using the given PA
+ target_paddr = positive_stride ? (pkt->req->getPaddr() +
stride) :
+ (pkt->req->getPaddr() - stride);
} else {
- //negative stride
- target_addr = pkt->req->hasPaddr() -
- (pkt->req->getVaddr() - new_pfi.getAddr());
+ target_paddr = new_pfi.getAddr();
+ }
+ has_target_pa = true;
+ } else {
+ // Page crossing reference
+ if (useVirtualAddresses) {
+ translation_req =
std::make_shared<Request>(pkt->req->getAsid(),
+ new_pfi.getAddr(), blkSize, pkt->req->getFlags(), masterId,
+ new_pfi.getPC(), pkt->req->contextId());
+ if (translateVirtualAddress(translation_req)) {
+ target_paddr = translation_req->getPaddr();
+ has_target_pa = true;
+ }
+ // If the translation failed, this prefetch will be queued in
+ // the missing-translation queue
+ } else {
+ // page-crossing with PA, we need the VA to navigate to the
+ // adjacent page
+ if (pkt->req->hasVaddr()) {
+ // Compute the target VA using req->getVaddr + stride
+ Addr target_vaddr = positive_stride ?
+ (pkt->req->getVaddr() + stride) :
+ (pkt->req->getVaddr() - stride);
+ translation_req = std::make_shared<Request>(
+ pkt->req->getAsid(), target_vaddr, blkSize,
+ pkt->req->getFlags(), masterId, new_pfi.getPC(),
+ pkt->req->contextId());
+ if (translateVirtualAddress(translation_req)) {
+ target_paddr = translation_req->getPaddr();
+ has_target_pa = true;
+ }
+ // If the translation failed, this prefetch will be queued
in
+ // the missing-translation queue
+ } else {
+ // Can not cross page without VA
+ DPRINTF(HWPrefetch, "Droping prefetch for address %#x, "
+ "missing vaddr\n", orig_addr);
+ return;
+ }
}
}
-
- if (cacheSnoop && (inCache(target_addr, new_pfi.isSecure()) ||
- inMissQueue(target_addr, new_pfi.isSecure()))) {
+ if (has_target_pa && cacheSnoop &&
+ (inCache(target_paddr, new_pfi.isSecure()) ||
+ inMissQueue(target_paddr, new_pfi.isSecure()))) {
pfInCache++;
DPRINTF(HWPrefetch, "Dropping redundant in "
- "cache/MSHR prefetch addr:%#x\n", target_addr);
+ "cache/MSHR prefetch addr:%#x\n", target_paddr);
return;
}

- /* Create a prefetch memory request */
- RequestPtr pf_req =
- std::make_shared<Request>(target_addr, blkSize, 0, masterId);
-
- if (new_pfi.isSecure()) {
- pf_req->setFlags(Request::SECURE);
+ /* Create the packet and find the spot to insert it */
+ DeferredPacket dpp(new_pfi, 0, priority);
+ if (has_target_pa) {
+ Tick pf_time = curTick() + clockPeriod() * latency;
+ dpp.createPkt(target_paddr, blkSize, masterId, tagPrefetch,
pf_time);
+ DPRINTF(HWPrefetch, "Prefetch queued. "
+ "addr:%#x priority: %3d tick:%lld.\n",
+ new_pfi.getAddr(), priority, pf_time);
+ addToQueue(pfq, dpp);
+ } else {
+ // Add the translation request and try to resolve it later
+ dpp.setTranslationRequest(translation_req);
+ DPRINTF(HWPrefetch, "Prefetch queued with no translation. "
+ "addr:%#x priority: %3d\n", new_pfi.getAddr(), priority);
+ addToQueue(pfqMissingTranslation, dpp);
}
- pf_req->taskId(ContextSwitchTaskId::Prefetcher);
- PacketPtr pf_pkt = new Packet(pf_req, MemCmd::HardPFReq);
- pf_pkt->allocate();
- if (tagPrefetch && new_pfi.hasPC()) {
- // Tag prefetch packet with accessing pc
- pf_pkt->req->setPC(new_pfi.getPC());
- }
+}

+void
+QueuedPrefetcher::addToQueue(std::list<DeferredPacket> &queue,
+ DeferredPacket &dpp)
+{
/* Verify prefetch buffer space for request */
- if (pfq.size() == queueSize) {
+ if (queue.size() == queueSize) {
pfRemovedFull++;
/* Lowest priority packet */
- iterator it = pfq.end();
- panic_if (it == pfq.begin(), "Prefetch queue is both full and
empty!");
+ iterator it = queue.end();
+ panic_if (it == queue.begin(),
+ "Prefetch queue is both full and empty!");
--it;
/* Look for oldest in that level of priority */
- panic_if (it == pfq.begin(), "Prefetch queue is full with 1
element!");
+ panic_if (it == queue.begin(),
+ "Prefetch queue is full with 1 element!");
iterator prev = it;
bool cont = true;
/* While not at the head of the queue */
- while (cont && prev != pfq.begin()) {
+ while (cont && prev != queue.begin()) {
prev--;
/* While at the same level of priority */
cont = prev->priority == it->priority;
@@ -262,27 +413,20 @@
DPRINTF(HWPrefetch, "Prefetch queue full, removing lowest
priority "
"oldest packet, addr: %#x",
it->pfInfo.getAddr());
delete it->pkt;
- pfq.erase(it);
+ queue.erase(it);
}

- Tick pf_time = curTick() + clockPeriod() * latency;
- DPRINTF(HWPrefetch, "Prefetch queued. "
- "addr:%#x priority: %3d tick:%lld.\n",
- target_addr, priority, pf_time);
-
- /* Create the packet and find the spot to insert it */
- DeferredPacket dpp(new_pfi, pf_time, pf_pkt, priority);
- if (pfq.size() == 0) {
- pfq.emplace_back(dpp);
+ if (queue.size() == 0) {
+ queue.emplace_back(dpp);
} else {
- iterator it = pfq.end();
+ iterator it = queue.end();
do {
--it;
- } while (it != pfq.begin() && dpp > *it);
+ } while (it != queue.begin() && dpp > *it);
/* If we reach the head, we have to see if the new element is new
head
* or not */
- if (it == pfq.begin() && dpp <= *it)
+ if (it == queue.begin() && dpp <= *it)
it++;
- pfq.insert(it, dpp);
+ queue.insert(it, dpp);
}
}
diff --git a/src/mem/cache/prefetch/queued.hh
b/src/mem/cache/prefetch/queued.hh
index c9a61c0..9759ece 100644
--- a/src/mem/cache/prefetch/queued.hh
+++ b/src/mem/cache/prefetch/queued.hh
@@ -63,20 +63,18 @@
PacketPtr pkt;
/** The priority of this prefetch */
int32_t priority;
+ /** Request used when a translation is needed */
+ RequestPtr translationRequest;

/**
* Constructor
* @param pfi PrefechInfo object associated to this packet
* @param t Time when this prefetch becomes ready
* @param prio This prefetch priority
- * @param blk_size block size used by the prefetcher
- * @param mid Requester ID of the access that generated this
prefetch
- * @param tag_prefetch flag to indicate if the packet needs to be
- * tagged
*/
- DeferredPacket(PrefetchInfo const &pfi, Tick t, PacketPtr p,
- int32_t prio) : pfInfo(pfi), tick(t), pkt(p),
- priority(prio) {
+ DeferredPacket(PrefetchInfo const &pfi, Tick t, int32_t prio) :
+ pfInfo(pfi), tick(t), pkt(nullptr), priority(prio),
+ translationRequest() {
}

bool operator>(const DeferredPacket& that) const
@@ -91,16 +89,48 @@
{
return !(*this > that);
}
+
+ /**
+ * Create the associated memory packet
+ * @param paddr physical address of this packet
+ * @param blk_size block size used by the prefetcher
+ * @param mid Requester ID of the access that generated this
prefetch
+ * @param tag_prefetch flag to indicate if the packet needs to be
+ * tagged
+ * @param t time when the prefetch becomes ready
+ */
+ void createPkt(Addr paddr, unsigned blk_size, MasterID mid,
+ bool tag_prefetch, Tick t);
+
+ /**
+ * Sets the translation request needed to obtain the physical
address
+ * of this request.
+ * @param req The Request with the virtual address of this request
+ */
+ void setTranslationRequest(const RequestPtr &req)
+ {
+ translationRequest = req;
+ }
};
using AddrPriority = std::pair<Addr, int32_t>;

std::list<DeferredPacket> pfq;
+ std::list<DeferredPacket> pfqMissingTranslation;
+
+ using const_iterator = std::list<DeferredPacket>::const_iterator;
+ using iterator = std::list<DeferredPacket>::iterator;

// PARAMETERS

/** Maximum size of the prefetch queue */
const unsigned queueSize;

+ /**
+ * Maximum size of the queue holding prefetch requests with missing
+ * address translations
+ */
+ const unsigned missingTranslationQueueSize;
+
/** Cycles after generation when a prefetch can first be issued */
const Cycles latency;

@@ -116,11 +146,6 @@
/** Tag prefetch with PC of generating access? */
const bool tagPrefetch;

- using const_iterator = std::list<DeferredPacket>::const_iterator;
- const_iterator inPrefetch(const PrefetchInfo &pfi) const;
- using iterator = std::list<DeferredPacket>::iterator;
- iterator inPrefetch(const PrefetchInfo &pfi);
-
// STATS
Stats::Scalar pfIdentified;
Stats::Scalar pfBufferHit;
@@ -146,6 +171,43 @@
}

void regStats() override;
+
+ private:
+
+ /**
+ * Adds a DeferredPacket to the specified queue
+ * @param queue selected queue to use
+ * @param dpp DeferredPacket to add
+ */
+ void addToQueue(std::list<DeferredPacket> &queue, DeferredPacket &dpp);
+
+ /**
+ * Tries to obtain the physical address of a virtual address
+ * It does so issuing requests to the data TLBs of the system
+ * @param req RequestPtr containing the virtual address to be
translated
+ * @return true if the translation has succeeded
+ */
+ bool translateVirtualAddress(const RequestPtr &req) const;
+
+ /**
+ * Attempts to pefrorm translations of the queued prefetches with a
+ * missing translation. It performs a maximum specified number of
+ * translations. Successful translations cause the prefetch request to
be
+ * queued in the queue of ready requests.
+ * @param max maximum number of translations to perform
+ */
+ void attemptMissingTranslations(unsigned max);
+
+ /**
+ * Checks whether the specified prefetch request is already in the
+ * specified queue. If the request is found, its priority is updated.
+ * @param queue selected queue to check
+ * @param pfi information of the prefetch request to be added
+ * @param priority priority of the prefetch request to be added
+ * @return True if the prefetch request was found in the queue
+ */
+ bool alreadyInQueue(std::list<DeferredPacket> &queue,
+ const PrefetchInfo &pfi, int32_t priority);
};

#endif //__MEM_CACHE_PREFETCH_QUEUED_HH__
diff --git a/src/mem/cache/prefetch/stride.cc
b/src/mem/cache/prefetch/stride.cc
index 5d00901..d45ca04 100644
--- a/src/mem/cache/prefetch/stride.cc
+++ b/src/mem/cache/prefetch/stride.cc
@@ -195,15 +195,8 @@
}

Addr new_addr = pf_addr + d * prefetch_stride;
- if (samePage(pf_addr, new_addr)) {
- DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n",
new_addr);
- addresses.push_back(AddrPriority(new_addr, 0));
- } else {
- // Record the number of page crossing prefetches generated
- pfSpanPage += degree - d + 1;
- DPRINTF(HWPrefetch, "Ignoring page crossing prefetch.\n");
- return;
- }
+ DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", new_addr);
+ addresses.push_back(AddrPriority(new_addr, 0));
}
} else {
// Miss in table
diff --git a/src/mem/cache/prefetch/tagged.cc
b/src/mem/cache/prefetch/tagged.cc
index a360cc6..1623817 100644
--- a/src/mem/cache/prefetch/tagged.cc
+++ b/src/mem/cache/prefetch/tagged.cc
@@ -51,13 +51,7 @@

for (int d = 1; d <= degree; d++) {
Addr newAddr = blkAddr + d*(blkSize);
- if (!samePage(blkAddr, newAddr)) {
- // Count number of unissued prefetches due to page crossing
- pfSpanPage += degree - d + 1;
- return;
- } else {
- addresses.push_back(AddrPriority(newAddr,0));
- }
+ addresses.push_back(AddrPriority(newAddr,0));
}
}
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/14620
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: Ib56374097e3b7dc87414139d210ea9272f96b06b
Gerrit-Change-Number: 14620
Gerrit-PatchSet: 1
Gerrit-Owner: Javier Bueno Hedo <***@metempsy.com>
Gerrit-Reviewer: Andreas Sandberg <***@arm.com>
Gerrit-Reviewer: Giacomo Travaglini <***@arm.com>
Gerrit-MessageType: newchange
Javier Bueno Hedo (Gerrit)
2018-11-29 13:06:42 UTC
Permalink
Hello Jason Lowe-Power, Nikos Nikoleris, Daniel Carvalho, Giacomo
Travaglini, Andreas Sandberg,

I'd like you to reexamine a change. Please visit

https://gem5-review.googlesource.com/c/public/gem5/+/14620

to look at the new patch set (#2).

Change subject: mem-cache: Support for page crossing prefetches
......................................................................

mem-cache: Support for page crossing prefetches

Prefetchers can now issue hardware prefetch requests that go beyond
the boundaries of the system page. Page crossing references will need
to look up the TLBs to be able to compute the physical address to be
prefetched.

Change-Id: Ib56374097e3b7dc87414139d210ea9272f96b06b
---
M src/mem/cache/prefetch/Prefetcher.py
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/cache/prefetch/queued.cc
M src/mem/cache/prefetch/queued.hh
M src/mem/cache/prefetch/stride.cc
M src/mem/cache/prefetch/tagged.cc
7 files changed, 331 insertions(+), 129 deletions(-)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/14620
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: Ib56374097e3b7dc87414139d210ea9272f96b06b
Gerrit-Change-Number: 14620
Gerrit-PatchSet: 2
Gerrit-Owner: Javier Bueno Hedo <***@metempsy.com>
Gerrit-Reviewer: Andreas Sandberg <***@arm.com>
Gerrit-Reviewer: Daniel Carvalho <***@yahoo.com.br>
Gerrit-Reviewer: Giacomo Travaglini <***@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <***@lowepower.com>
Gerrit-Reviewer: Javier Bueno Hedo <***@metempsy.com>
Gerrit-Reviewer: Nikos Nikoleris <***@arm.com>
Gerrit-MessageType: newpatchset
Javier Bueno Hedo (Gerrit)
2018-11-29 15:44:05 UTC
Permalink
Hello Jason Lowe-Power, Nikos Nikoleris, Daniel Carvalho, Giacomo
Travaglini, Andreas Sandberg,

I'd like you to reexamine a change. Please visit

https://gem5-review.googlesource.com/c/public/gem5/+/14620

to look at the new patch set (#3).

Change subject: mem-cache: Support for page crossing prefetches
......................................................................

mem-cache: Support for page crossing prefetches

Prefetchers can now issue hardware prefetch requests that go beyond
the boundaries of the system page. Page crossing references will need
to look up the TLBs to be able to compute the physical address to be
prefetched.

Change-Id: Ib56374097e3b7dc87414139d210ea9272f96b06b
---
M src/mem/cache/prefetch/Prefetcher.py
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/cache/prefetch/queued.cc
M src/mem/cache/prefetch/queued.hh
5 files changed, 324 insertions(+), 96 deletions(-)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/14620
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: Ib56374097e3b7dc87414139d210ea9272f96b06b
Gerrit-Change-Number: 14620
Gerrit-PatchSet: 3
Gerrit-Owner: Javier Bueno Hedo <***@metempsy.com>
Gerrit-Reviewer: Andreas Sandberg <***@arm.com>
Gerrit-Reviewer: Daniel Carvalho <***@yahoo.com.br>
Gerrit-Reviewer: Giacomo Travaglini <***@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <***@lowepower.com>
Gerrit-Reviewer: Javier Bueno Hedo <***@metempsy.com>
Gerrit-Reviewer: Nikos Nikoleris <***@arm.com>
Gerrit-MessageType: newpatchset
Continue reading on narkive:
Loading...