mem-cache: virtual address support for prefetchers
Prefetchers can be configured to operate with virtual or physical addreses. The option can be configured through the "use_virtual_addresses" parameter of the Prefetcher object. Change-Id: I4f8c3687988afecc8a91c3c5b2d44cc0580f72aa Reviewed-on: https://gem5-review.googlesource.com/c/14416 Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
This commit is contained in:
committed by
Javier Bueno Hedo
parent
cba75858ab
commit
38f87dab68
2
src/mem/cache/prefetch/Prefetcher.py
vendored
2
src/mem/cache/prefetch/Prefetcher.py
vendored
@@ -76,6 +76,8 @@ class BasePrefetcher(ClockedObject):
|
||||
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)")
|
||||
use_virtual_addresses = Param.Bool(False,
|
||||
"Use virtual addresses for prefetching")
|
||||
|
||||
_events = []
|
||||
def addEvent(self, newObject):
|
||||
|
||||
28
src/mem/cache/prefetch/base.cc
vendored
28
src/mem/cache/prefetch/base.cc
vendored
@@ -56,6 +56,19 @@
|
||||
#include "params/BasePrefetcher.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
BasePrefetcher::PrefetchInfo::PrefetchInfo(PacketPtr pkt, Addr addr)
|
||||
: address(addr), pc(pkt->req->hasPC() ? pkt->req->getPC() : 0),
|
||||
masterId(pkt->req->masterId()), validPC(pkt->req->hasPC()),
|
||||
secure(pkt->isSecure())
|
||||
{
|
||||
}
|
||||
|
||||
BasePrefetcher::PrefetchInfo::PrefetchInfo(PrefetchInfo const &pfi, Addr addr)
|
||||
: address(addr), pc(pfi.pc), masterId(pfi.masterId), validPC(pfi.validPC),
|
||||
secure(pfi.secure)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BasePrefetcher::PrefetchListener::notify(const PacketPtr &pkt)
|
||||
{
|
||||
@@ -67,7 +80,8 @@ BasePrefetcher::BasePrefetcher(const BasePrefetcherParams *p)
|
||||
lBlkSize(floorLog2(blkSize)), onMiss(p->on_miss), onRead(p->on_read),
|
||||
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)
|
||||
prefetchOnAccess(p->prefetch_on_access),
|
||||
useVirtualAddresses(p->use_virtual_addresses)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -175,7 +189,17 @@ BasePrefetcher::probeNotify(const PacketPtr &pkt)
|
||||
if (pkt->cmd.isSWPrefetch()) return;
|
||||
if (pkt->req->isCacheMaintenance()) return;
|
||||
if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return;
|
||||
notify(pkt);
|
||||
|
||||
// Verify this access type is observed by prefetcher
|
||||
if (observeAccess(pkt)) {
|
||||
if (useVirtualAddresses && pkt->req->hasVaddr()) {
|
||||
PrefetchInfo pfi(pkt, pkt->req->getVaddr());
|
||||
notify(pkt, pfi);
|
||||
} else if (!useVirtualAddresses && pkt->req->hasPaddr()) {
|
||||
PrefetchInfo pfi(pkt, pkt->req->getPaddr());
|
||||
notify(pkt, pfi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
96
src/mem/cache/prefetch/base.hh
vendored
96
src/mem/cache/prefetch/base.hh
vendored
@@ -78,6 +78,96 @@ class BasePrefetcher : public ClockedObject
|
||||
std::vector<PrefetchListener *> listeners;
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Class containing the information needed by the prefetch to train and
|
||||
* generate new prefetch requests.
|
||||
*/
|
||||
class PrefetchInfo {
|
||||
/** The address. */
|
||||
Addr address;
|
||||
/** The program counter that generated this address. */
|
||||
Addr pc;
|
||||
/** The requestor ID that generated this address. */
|
||||
MasterID masterId;
|
||||
/** Validity bit for the PC of this address. */
|
||||
bool validPC;
|
||||
/** Whether this address targets the secure memory space. */
|
||||
bool secure;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Obtains the address value of this Prefetcher address.
|
||||
* @return the addres value.
|
||||
*/
|
||||
Addr getAddr() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the address targets the secure memory space.
|
||||
* @return true if the address targets the secure memory space.
|
||||
*/
|
||||
bool isSecure() const
|
||||
{
|
||||
return secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the program counter that generated this request.
|
||||
* @return the pc value
|
||||
*/
|
||||
Addr getPC() const
|
||||
{
|
||||
assert(hasPC());
|
||||
return pc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the associated program counter is valid
|
||||
* @return true if the program counter has a valid value
|
||||
*/
|
||||
bool hasPC() const
|
||||
{
|
||||
return validPC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the requestor ID that generated this address
|
||||
* @return the requestor ID that generated this address
|
||||
*/
|
||||
MasterID getMasterId() const
|
||||
{
|
||||
return masterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for equality
|
||||
* @param pfi PrefetchInfo to compare against
|
||||
* @return True if this object and the provided one are equal
|
||||
*/
|
||||
bool sameAddr(PrefetchInfo const &pfi) const
|
||||
{
|
||||
return this->getAddr() == pfi.getAddr() &&
|
||||
this->isSecure() == pfi.isSecure();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PrefetchInfo using a PacketPtr.
|
||||
* @param pkt PacketPtr used to generate the PrefetchInfo
|
||||
* @param addr the address value of the new object
|
||||
*/
|
||||
PrefetchInfo(PacketPtr pkt, Addr addr);
|
||||
|
||||
/**
|
||||
* Constructs a PrefetchInfo using a new address value and
|
||||
* another PrefetchInfo as a reference.
|
||||
* @param pfi PrefetchInfo used to generate this new object
|
||||
* @param addr the address value of the new object
|
||||
*/
|
||||
PrefetchInfo(PrefetchInfo const &pfi, Addr addr);
|
||||
};
|
||||
|
||||
// PARAMETERS
|
||||
|
||||
/** Pointr to the parent cache. */
|
||||
@@ -112,6 +202,9 @@ class BasePrefetcher : public ClockedObject
|
||||
/** Prefetch on every access, not just misses */
|
||||
const bool prefetchOnAccess;
|
||||
|
||||
/** Use Virtual Addresses for prefetching */
|
||||
const bool useVirtualAddresses;
|
||||
|
||||
/** Determine if this access should be observed */
|
||||
bool observeAccess(const PacketPtr &pkt) const;
|
||||
|
||||
@@ -134,7 +227,6 @@ class BasePrefetcher : public ClockedObject
|
||||
/** Build the address of the i-th block inside the page */
|
||||
Addr pageIthBlockAddress(Addr page, uint32_t i) const;
|
||||
|
||||
|
||||
Stats::Scalar pfIssued;
|
||||
|
||||
public:
|
||||
@@ -149,7 +241,7 @@ class BasePrefetcher : public ClockedObject
|
||||
* Notify prefetcher of cache access (may be any access or just
|
||||
* misses, depending on cache parameters.)
|
||||
*/
|
||||
virtual void notify(const PacketPtr &pkt) = 0;
|
||||
virtual void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) = 0;
|
||||
|
||||
virtual PacketPtr getPacket() = 0;
|
||||
|
||||
|
||||
129
src/mem/cache/prefetch/queued.cc
vendored
129
src/mem/cache/prefetch/queued.cc
vendored
@@ -64,50 +64,43 @@ QueuedPrefetcher::~QueuedPrefetcher()
|
||||
}
|
||||
|
||||
void
|
||||
QueuedPrefetcher::notify(const PacketPtr &pkt)
|
||||
QueuedPrefetcher::notify(const PacketPtr &pkt, const PrefetchInfo &pfi)
|
||||
{
|
||||
// Verify this access type is observed by prefetcher
|
||||
if (observeAccess(pkt)) {
|
||||
Addr blk_addr = pkt->getBlockAddr(blkSize);
|
||||
bool is_secure = pkt->isSecure();
|
||||
Addr blk_addr = blockAddress(pfi.getAddr());
|
||||
bool is_secure = pfi.isSecure();
|
||||
|
||||
// Squash queued prefetches if demand miss to same line
|
||||
if (queueSquash) {
|
||||
auto itr = pfq.begin();
|
||||
while (itr != pfq.end()) {
|
||||
if (itr->pkt->getAddr() == blk_addr &&
|
||||
itr->pkt->isSecure() == is_secure) {
|
||||
delete itr->pkt;
|
||||
itr = pfq.erase(itr);
|
||||
} else {
|
||||
++itr;
|
||||
}
|
||||
// Squash queued prefetches if demand miss to same line
|
||||
if (queueSquash) {
|
||||
auto itr = pfq.begin();
|
||||
while (itr != pfq.end()) {
|
||||
if (itr->pfInfo.getAddr() == blk_addr &&
|
||||
itr->pfInfo.isSecure() == is_secure) {
|
||||
delete itr->pkt;
|
||||
itr = pfq.erase(itr);
|
||||
} else {
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate prefetches given this access
|
||||
std::vector<AddrPriority> addresses;
|
||||
calculatePrefetch(pkt, addresses);
|
||||
// Calculate prefetches given this access
|
||||
std::vector<AddrPriority> addresses;
|
||||
calculatePrefetch(pfi, addresses);
|
||||
|
||||
// Queue up generated prefetches
|
||||
for (AddrPriority& pf_info : addresses) {
|
||||
// Block align prefetch address
|
||||
pf_info.first = blockAddress(pf_info.first);
|
||||
// Queue up generated prefetches
|
||||
for (AddrPriority& addr_prio : addresses) {
|
||||
|
||||
pfIdentified++;
|
||||
DPRINTF(HWPrefetch, "Found a pf candidate addr: %#x, "
|
||||
"inserting into prefetch queue.\n", pf_info.first);
|
||||
// Block align prefetch address
|
||||
addr_prio.first = blockAddress(addr_prio.first);
|
||||
|
||||
// Create and insert the request
|
||||
PacketPtr pf_pkt = insert(pf_info, is_secure);
|
||||
PrefetchInfo new_pfi(pfi,addr_prio.first);
|
||||
|
||||
if (pf_pkt != nullptr) {
|
||||
if (tagPrefetch && pkt->req->hasPC()) {
|
||||
// Tag prefetch packet with accessing pc
|
||||
pf_pkt->req->setPC(pkt->req->getPC());
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +114,7 @@ QueuedPrefetcher::getPacket()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PacketPtr pkt = pfq.begin()->pkt;
|
||||
PacketPtr pkt = pfq.front().pkt;
|
||||
pfq.pop_front();
|
||||
|
||||
pfIssued++;
|
||||
@@ -131,22 +124,20 @@ QueuedPrefetcher::getPacket()
|
||||
}
|
||||
|
||||
QueuedPrefetcher::const_iterator
|
||||
QueuedPrefetcher::inPrefetch(Addr address, bool is_secure) const
|
||||
QueuedPrefetcher::inPrefetch(const PrefetchInfo &pfi) const
|
||||
{
|
||||
for (const_iterator dp = pfq.begin(); dp != pfq.end(); dp++) {
|
||||
if ((*dp).pkt->getAddr() == address &&
|
||||
(*dp).pkt->isSecure() == is_secure) return dp;
|
||||
if (dp->pfInfo.sameAddr(pfi)) return dp;
|
||||
}
|
||||
|
||||
return pfq.end();
|
||||
}
|
||||
|
||||
QueuedPrefetcher::iterator
|
||||
QueuedPrefetcher::inPrefetch(Addr address, bool is_secure)
|
||||
QueuedPrefetcher::inPrefetch(const PrefetchInfo &pfi)
|
||||
{
|
||||
for (iterator dp = pfq.begin(); dp != pfq.end(); dp++) {
|
||||
if (dp->pkt->getAddr() == address &&
|
||||
dp->pkt->isSecure() == is_secure) return dp;
|
||||
if (dp->pfInfo.sameAddr(pfi)) return dp;
|
||||
}
|
||||
|
||||
return pfq.end();
|
||||
@@ -178,17 +169,18 @@ QueuedPrefetcher::regStats()
|
||||
.desc("number of prefetches not generated due to page crossing");
|
||||
}
|
||||
|
||||
PacketPtr
|
||||
QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure)
|
||||
void
|
||||
QueuedPrefetcher::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
|
||||
int32_t priority)
|
||||
{
|
||||
if (queueFilter) {
|
||||
iterator it = inPrefetch(pf_info.first, is_secure);
|
||||
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 < pf_info.second) {
|
||||
if (it->priority < priority) {
|
||||
/* Update priority value and position in the queue */
|
||||
it->priority = pf_info.second;
|
||||
it->priority = priority;
|
||||
iterator prev = it;
|
||||
bool cont = true;
|
||||
while (cont && prev != pfq.begin()) {
|
||||
@@ -205,28 +197,47 @@ QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure)
|
||||
DPRINTF(HWPrefetch, "Prefetch addr already in "
|
||||
"prefetch queue\n");
|
||||
}
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheSnoop && (inCache(pf_info.first, is_secure) ||
|
||||
inMissQueue(pf_info.first, is_secure))) {
|
||||
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->getPaddr() +
|
||||
(new_pfi.getAddr() - pkt->req->getVaddr());
|
||||
} else {
|
||||
//negative stride
|
||||
target_addr = pkt->req->getPaddr() -
|
||||
(pkt->req->getVaddr() - new_pfi.getAddr());
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheSnoop && (inCache(target_addr, new_pfi.isSecure()) ||
|
||||
inMissQueue(target_addr, new_pfi.isSecure()))) {
|
||||
pfInCache++;
|
||||
DPRINTF(HWPrefetch, "Dropping redundant in "
|
||||
"cache/MSHR prefetch addr:%#x\n", pf_info.first);
|
||||
return nullptr;
|
||||
"cache/MSHR prefetch addr:%#x\n", target_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a prefetch memory request */
|
||||
RequestPtr pf_req =
|
||||
std::make_shared<Request>(pf_info.first, blkSize, 0, masterId);
|
||||
std::make_shared<Request>(target_addr, blkSize, 0, masterId);
|
||||
|
||||
if (is_secure) {
|
||||
if (new_pfi.isSecure()) {
|
||||
pf_req->setFlags(Request::SECURE);
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
/* Verify prefetch buffer space for request */
|
||||
if (pfq.size() == queueSize) {
|
||||
@@ -243,13 +254,13 @@ QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure)
|
||||
while (cont && prev != pfq.begin()) {
|
||||
prev--;
|
||||
/* While at the same level of priority */
|
||||
cont = (*prev).priority == (*it).priority;
|
||||
cont = prev->priority == it->priority;
|
||||
if (cont)
|
||||
/* update pointer */
|
||||
it = prev;
|
||||
}
|
||||
DPRINTF(HWPrefetch, "Prefetch queue full, removing lowest priority "
|
||||
"oldest packet, addr: %#x", it->pkt->getAddr());
|
||||
"oldest packet, addr: %#x", it->pfInfo.getAddr());
|
||||
delete it->pkt;
|
||||
pfq.erase(it);
|
||||
}
|
||||
@@ -257,10 +268,10 @@ QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure)
|
||||
Tick pf_time = curTick() + clockPeriod() * latency;
|
||||
DPRINTF(HWPrefetch, "Prefetch queued. "
|
||||
"addr:%#x priority: %3d tick:%lld.\n",
|
||||
pf_info.first, pf_info.second, pf_time);
|
||||
target_addr, priority, pf_time);
|
||||
|
||||
/* Create the packet and find the spot to insert it */
|
||||
DeferredPacket dpp(pf_time, pf_pkt, pf_info.second);
|
||||
DeferredPacket dpp(new_pfi, pf_time, pf_pkt, priority);
|
||||
if (pfq.size() == 0) {
|
||||
pfq.emplace_back(dpp);
|
||||
} else {
|
||||
@@ -274,6 +285,4 @@ QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure)
|
||||
it++;
|
||||
pfq.insert(it, dpp);
|
||||
}
|
||||
|
||||
return pf_pkt;
|
||||
}
|
||||
|
||||
30
src/mem/cache/prefetch/queued.hh
vendored
30
src/mem/cache/prefetch/queued.hh
vendored
@@ -55,11 +55,27 @@ class QueuedPrefetcher : public BasePrefetcher
|
||||
{
|
||||
protected:
|
||||
struct DeferredPacket {
|
||||
/** Prefetch info corresponding to this packet */
|
||||
PrefetchInfo pfInfo;
|
||||
/** Time when this prefetch becomes ready */
|
||||
Tick tick;
|
||||
/** The memory packet generated by this prefetch */
|
||||
PacketPtr pkt;
|
||||
/** The priority of this prefetch */
|
||||
int32_t priority;
|
||||
DeferredPacket(Tick t, PacketPtr p, int32_t pr) : tick(t), pkt(p),
|
||||
priority(pr) {}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param pfi PrefechInfo object associated to this packet
|
||||
* @param t Time when this prefetch becomes ready
|
||||
* @param p PacketPtr with the memory request of the prefetch
|
||||
* @param prio This prefetch priority
|
||||
*/
|
||||
DeferredPacket(PrefetchInfo const &pfi, Tick t, PacketPtr p,
|
||||
int32_t prio) : pfInfo(pfi), tick(t), pkt(p),
|
||||
priority(prio) {
|
||||
}
|
||||
|
||||
bool operator>(const DeferredPacket& that) const
|
||||
{
|
||||
return priority > that.priority;
|
||||
@@ -98,9 +114,9 @@ class QueuedPrefetcher : public BasePrefetcher
|
||||
const bool tagPrefetch;
|
||||
|
||||
using const_iterator = std::list<DeferredPacket>::const_iterator;
|
||||
const_iterator inPrefetch(Addr address, bool is_secure) const;
|
||||
const_iterator inPrefetch(const PrefetchInfo &pfi) const;
|
||||
using iterator = std::list<DeferredPacket>::iterator;
|
||||
iterator inPrefetch(Addr address, bool is_secure);
|
||||
iterator inPrefetch(const PrefetchInfo &pfi);
|
||||
|
||||
// STATS
|
||||
Stats::Scalar pfIdentified;
|
||||
@@ -113,11 +129,11 @@ class QueuedPrefetcher : public BasePrefetcher
|
||||
QueuedPrefetcher(const QueuedPrefetcherParams *p);
|
||||
virtual ~QueuedPrefetcher();
|
||||
|
||||
void notify(const PacketPtr &pkt) override;
|
||||
void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) override;
|
||||
|
||||
PacketPtr insert(AddrPriority& info, bool is_secure);
|
||||
void insert(const PacketPtr &pkt, PrefetchInfo &new_pfi, int32_t priority);
|
||||
|
||||
virtual void calculatePrefetch(const PacketPtr &pkt,
|
||||
virtual void calculatePrefetch(const PrefetchInfo &pfi,
|
||||
std::vector<AddrPriority> &addresses) = 0;
|
||||
PacketPtr getPacket() override;
|
||||
|
||||
|
||||
28
src/mem/cache/prefetch/stride.cc
vendored
28
src/mem/cache/prefetch/stride.cc
vendored
@@ -138,19 +138,19 @@ StridePrefetcher::PCTable::~PCTable()
|
||||
}
|
||||
|
||||
void
|
||||
StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
StridePrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
|
||||
std::vector<AddrPriority> &addresses)
|
||||
{
|
||||
if (!pkt->req->hasPC()) {
|
||||
if (!pfi.hasPC()) {
|
||||
DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get required packet info
|
||||
Addr pkt_addr = pkt->getAddr();
|
||||
Addr pc = pkt->req->getPC();
|
||||
bool is_secure = pkt->isSecure();
|
||||
MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
|
||||
Addr pf_addr = pfi.getAddr();
|
||||
Addr pc = pfi.getPC();
|
||||
bool is_secure = pfi.isSecure();
|
||||
MasterID master_id = useMasterId ? pfi.getMasterId() : 0;
|
||||
|
||||
// Get corresponding pc table
|
||||
PCTable* pcTable = findTable(master_id);
|
||||
@@ -160,7 +160,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
|
||||
if (entry != nullptr) {
|
||||
// Hit in table
|
||||
int new_stride = pkt_addr - entry->lastAddr;
|
||||
int new_stride = pf_addr - entry->lastAddr;
|
||||
bool stride_match = (new_stride == entry->stride);
|
||||
|
||||
// Adjust confidence for stride entry
|
||||
@@ -176,11 +176,11 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
}
|
||||
|
||||
DPRINTF(HWPrefetch, "Hit: PC %x pkt_addr %x (%s) stride %d (%s), "
|
||||
"conf %d\n", pc, pkt_addr, is_secure ? "s" : "ns", new_stride,
|
||||
stride_match ? "match" : "change",
|
||||
"conf %d\n", pc, pf_addr, is_secure ? "s" : "ns",
|
||||
new_stride, stride_match ? "match" : "change",
|
||||
entry->confidence);
|
||||
|
||||
entry->lastAddr = pkt_addr;
|
||||
entry->lastAddr = pf_addr;
|
||||
|
||||
// Abort prefetch generation if below confidence threshold
|
||||
if (entry->confidence < threshConf)
|
||||
@@ -194,8 +194,8 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
prefetch_stride = (new_stride < 0) ? -blkSize : blkSize;
|
||||
}
|
||||
|
||||
Addr new_addr = pkt_addr + d * prefetch_stride;
|
||||
if (samePage(pkt_addr, new_addr)) {
|
||||
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 {
|
||||
@@ -207,7 +207,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
}
|
||||
} else {
|
||||
// Miss in table
|
||||
DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr,
|
||||
DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pf_addr,
|
||||
is_secure ? "s" : "ns");
|
||||
|
||||
StrideEntry* entry = pcTable->findVictim(pc);
|
||||
@@ -218,7 +218,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
|
||||
// Insert new entry's data
|
||||
entry->instAddr = pc;
|
||||
entry->lastAddr = pkt_addr;
|
||||
entry->lastAddr = pf_addr;
|
||||
entry->isSecure = is_secure;
|
||||
entry->confidence = startConf;
|
||||
replacementPolicy->reset(entry->replacementData);
|
||||
|
||||
2
src/mem/cache/prefetch/stride.hh
vendored
2
src/mem/cache/prefetch/stride.hh
vendored
@@ -172,7 +172,7 @@ class StridePrefetcher : public QueuedPrefetcher
|
||||
public:
|
||||
StridePrefetcher(const StridePrefetcherParams *p);
|
||||
|
||||
void calculatePrefetch(const PacketPtr &pkt,
|
||||
void calculatePrefetch(const PrefetchInfo &pfi,
|
||||
std::vector<AddrPriority> &addresses) override;
|
||||
};
|
||||
|
||||
|
||||
4
src/mem/cache/prefetch/tagged.cc
vendored
4
src/mem/cache/prefetch/tagged.cc
vendored
@@ -44,10 +44,10 @@ TaggedPrefetcher::TaggedPrefetcher(const TaggedPrefetcherParams *p)
|
||||
}
|
||||
|
||||
void
|
||||
TaggedPrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
||||
TaggedPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
|
||||
std::vector<AddrPriority> &addresses)
|
||||
{
|
||||
Addr blkAddr = pkt->getBlockAddr(blkSize);
|
||||
Addr blkAddr = blockAddress(pfi.getAddr());
|
||||
|
||||
for (int d = 1; d <= degree; d++) {
|
||||
Addr newAddr = blkAddr + d*(blkSize);
|
||||
|
||||
2
src/mem/cache/prefetch/tagged.hh
vendored
2
src/mem/cache/prefetch/tagged.hh
vendored
@@ -51,7 +51,7 @@ class TaggedPrefetcher : public QueuedPrefetcher
|
||||
|
||||
~TaggedPrefetcher() {}
|
||||
|
||||
void calculatePrefetch(const PacketPtr &pkt,
|
||||
void calculatePrefetch(const PrefetchInfo &pfi,
|
||||
std::vector<AddrPriority> &addresses) override;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user