mem-cache: Added extra information to PrefetchInfo
Added additional information to the PrefetchInfo data structure - Whether the event is triggered by a cache miss - Whether the event is a write or a read - Size of the data accessed - Data accessed by the request Change-Id: I070f3ffe837ea960a357388e7f2b8a61d7b2196c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/16583 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
a468635271
commit
b0d1643ddf
47
src/mem/cache/prefetch/base.cc
vendored
47
src/mem/cache/prefetch/base.cc
vendored
@@ -56,16 +56,26 @@
|
|||||||
#include "params/BasePrefetcher.hh"
|
#include "params/BasePrefetcher.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
BasePrefetcher::PrefetchInfo::PrefetchInfo(PacketPtr pkt, Addr addr)
|
BasePrefetcher::PrefetchInfo::PrefetchInfo(PacketPtr pkt, Addr addr, bool miss)
|
||||||
: address(addr), pc(pkt->req->hasPC() ? pkt->req->getPC() : 0),
|
: address(addr), pc(pkt->req->hasPC() ? pkt->req->getPC() : 0),
|
||||||
masterId(pkt->req->masterId()), validPC(pkt->req->hasPC()),
|
masterId(pkt->req->masterId()), validPC(pkt->req->hasPC()),
|
||||||
secure(pkt->isSecure())
|
secure(pkt->isSecure()), size(pkt->req->getSize()), write(pkt->isWrite()),
|
||||||
|
paddress(pkt->req->getPaddr()), cacheMiss(miss)
|
||||||
{
|
{
|
||||||
|
unsigned int req_size = pkt->req->getSize();
|
||||||
|
if (!write && miss) {
|
||||||
|
data = nullptr;
|
||||||
|
} else {
|
||||||
|
data = new uint8_t[req_size];
|
||||||
|
Addr offset = pkt->req->getPaddr() - pkt->getAddr();
|
||||||
|
std::memcpy(data, &(pkt->getConstPtr<uint8_t>()[offset]), req_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePrefetcher::PrefetchInfo::PrefetchInfo(PrefetchInfo const &pfi, Addr addr)
|
BasePrefetcher::PrefetchInfo::PrefetchInfo(PrefetchInfo const &pfi, Addr addr)
|
||||||
: address(addr), pc(pfi.pc), masterId(pfi.masterId), validPC(pfi.validPC),
|
: address(addr), pc(pfi.pc), masterId(pfi.masterId), validPC(pfi.validPC),
|
||||||
secure(pfi.secure)
|
secure(pfi.secure), size(pfi.size), write(pfi.write),
|
||||||
|
paddress(pfi.paddress), cacheMiss(pfi.cacheMiss), data(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +85,7 @@ BasePrefetcher::PrefetchListener::notify(const PacketPtr &pkt)
|
|||||||
if (isFill) {
|
if (isFill) {
|
||||||
parent.notifyFill(pkt);
|
parent.notifyFill(pkt);
|
||||||
} else {
|
} else {
|
||||||
parent.probeNotify(pkt);
|
parent.probeNotify(pkt, miss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,13 +124,11 @@ BasePrefetcher::regStats()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BasePrefetcher::observeAccess(const PacketPtr &pkt) const
|
BasePrefetcher::observeAccess(const PacketPtr &pkt, bool miss) const
|
||||||
{
|
{
|
||||||
Addr addr = pkt->getAddr();
|
|
||||||
bool fetch = pkt->req->isInstFetch();
|
bool fetch = pkt->req->isInstFetch();
|
||||||
bool read = pkt->isRead();
|
bool read = pkt->isRead();
|
||||||
bool inv = pkt->isInvalidate();
|
bool inv = pkt->isInvalidate();
|
||||||
bool is_secure = pkt->isSecure();
|
|
||||||
|
|
||||||
if (pkt->req->isUncacheable()) return false;
|
if (pkt->req->isUncacheable()) return false;
|
||||||
if (fetch && !onInst) return false;
|
if (fetch && !onInst) return false;
|
||||||
@@ -131,8 +139,7 @@ BasePrefetcher::observeAccess(const PacketPtr &pkt) const
|
|||||||
if (pkt->cmd == MemCmd::CleanEvict) return false;
|
if (pkt->cmd == MemCmd::CleanEvict) return false;
|
||||||
|
|
||||||
if (onMiss) {
|
if (onMiss) {
|
||||||
return !inCache(addr, is_secure) &&
|
return miss;
|
||||||
!inMissQueue(addr, is_secure);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -193,25 +200,28 @@ BasePrefetcher::pageIthBlockAddress(Addr page, uint32_t blockIndex) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BasePrefetcher::probeNotify(const PacketPtr &pkt)
|
BasePrefetcher::probeNotify(const PacketPtr &pkt, bool miss)
|
||||||
{
|
{
|
||||||
// Don't notify prefetcher on SWPrefetch, cache maintenance
|
// Don't notify prefetcher on SWPrefetch, cache maintenance
|
||||||
// operations or for writes that we are coaslescing.
|
// operations or for writes that we are coaslescing.
|
||||||
if (pkt->cmd.isSWPrefetch()) return;
|
if (pkt->cmd.isSWPrefetch()) return;
|
||||||
if (pkt->req->isCacheMaintenance()) return;
|
if (pkt->req->isCacheMaintenance()) return;
|
||||||
if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return;
|
if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return;
|
||||||
|
if (!pkt->req->hasPaddr()) {
|
||||||
|
panic("Request must have a physical address");
|
||||||
|
}
|
||||||
|
|
||||||
if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
|
if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
|
||||||
usefulPrefetches += 1;
|
usefulPrefetches += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify this access type is observed by prefetcher
|
// Verify this access type is observed by prefetcher
|
||||||
if (observeAccess(pkt)) {
|
if (observeAccess(pkt, miss)) {
|
||||||
if (useVirtualAddresses && pkt->req->hasVaddr()) {
|
if (useVirtualAddresses && pkt->req->hasVaddr()) {
|
||||||
PrefetchInfo pfi(pkt, pkt->req->getVaddr());
|
PrefetchInfo pfi(pkt, pkt->req->getVaddr(), miss);
|
||||||
notify(pkt, pfi);
|
notify(pkt, pfi);
|
||||||
} else if (!useVirtualAddresses && pkt->req->hasPaddr()) {
|
} else if (!useVirtualAddresses) {
|
||||||
PrefetchInfo pfi(pkt, pkt->req->getPaddr());
|
PrefetchInfo pfi(pkt, pkt->req->getPaddr(), miss);
|
||||||
notify(pkt, pfi);
|
notify(pkt, pfi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,10 +237,13 @@ BasePrefetcher::regProbeListeners()
|
|||||||
*/
|
*/
|
||||||
if (listeners.empty() && cache != nullptr) {
|
if (listeners.empty() && cache != nullptr) {
|
||||||
ProbeManager *pm(cache->getProbeManager());
|
ProbeManager *pm(cache->getProbeManager());
|
||||||
listeners.push_back(new PrefetchListener(*this, pm, "Miss"));
|
listeners.push_back(new PrefetchListener(*this, pm, "Miss", false,
|
||||||
listeners.push_back(new PrefetchListener(*this, pm, "Fill", true));
|
true));
|
||||||
|
listeners.push_back(new PrefetchListener(*this, pm, "Fill", true,
|
||||||
|
false));
|
||||||
if (prefetchOnAccess) {
|
if (prefetchOnAccess) {
|
||||||
listeners.push_back(new PrefetchListener(*this, pm, "Hit"));
|
listeners.push_back(new PrefetchListener(*this, pm, "Hit", false,
|
||||||
|
false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/mem/cache/prefetch/base.hh
vendored
105
src/mem/cache/prefetch/base.hh
vendored
@@ -51,10 +51,12 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "arch/isa_traits.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
#include "mem/request.hh"
|
#include "mem/request.hh"
|
||||||
|
#include "sim/byteswap.hh"
|
||||||
#include "sim/clocked_object.hh"
|
#include "sim/clocked_object.hh"
|
||||||
#include "sim/probe/probe.hh"
|
#include "sim/probe/probe.hh"
|
||||||
|
|
||||||
@@ -67,13 +69,15 @@ class BasePrefetcher : public ClockedObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrefetchListener(BasePrefetcher &_parent, ProbeManager *pm,
|
PrefetchListener(BasePrefetcher &_parent, ProbeManager *pm,
|
||||||
const std::string &name, bool _isFill = false)
|
const std::string &name, bool _isFill = false,
|
||||||
|
bool _miss = false)
|
||||||
: ProbeListenerArgBase(pm, name),
|
: ProbeListenerArgBase(pm, name),
|
||||||
parent(_parent), isFill(_isFill) {}
|
parent(_parent), isFill(_isFill), miss(_miss) {}
|
||||||
void notify(const PacketPtr &pkt) override;
|
void notify(const PacketPtr &pkt) override;
|
||||||
protected:
|
protected:
|
||||||
BasePrefetcher &parent;
|
BasePrefetcher &parent;
|
||||||
bool isFill;
|
const bool isFill;
|
||||||
|
const bool miss;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<PrefetchListener *> listeners;
|
std::vector<PrefetchListener *> listeners;
|
||||||
@@ -85,7 +89,7 @@ class BasePrefetcher : public ClockedObject
|
|||||||
* generate new prefetch requests.
|
* generate new prefetch requests.
|
||||||
*/
|
*/
|
||||||
class PrefetchInfo {
|
class PrefetchInfo {
|
||||||
/** The address. */
|
/** The address used to train and generate prefetches */
|
||||||
Addr address;
|
Addr address;
|
||||||
/** The program counter that generated this address. */
|
/** The program counter that generated this address. */
|
||||||
Addr pc;
|
Addr pc;
|
||||||
@@ -95,6 +99,16 @@ class BasePrefetcher : public ClockedObject
|
|||||||
bool validPC;
|
bool validPC;
|
||||||
/** Whether this address targets the secure memory space. */
|
/** Whether this address targets the secure memory space. */
|
||||||
bool secure;
|
bool secure;
|
||||||
|
/** Size in bytes of the request triggering this event */
|
||||||
|
unsigned int size;
|
||||||
|
/** Whether this event comes from a write request */
|
||||||
|
bool write;
|
||||||
|
/** Physical address, needed because address can be virtual */
|
||||||
|
Addr paddress;
|
||||||
|
/** Whether this event comes from a cache miss */
|
||||||
|
bool cacheMiss;
|
||||||
|
/** Pointer to the associated request data */
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -143,6 +157,67 @@ class BasePrefetcher : public ClockedObject
|
|||||||
return masterId;
|
return masterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the size of the request triggering this event
|
||||||
|
* @return the size in bytes of the request triggering this event
|
||||||
|
*/
|
||||||
|
unsigned int getSize() const
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the request that caused this prefetch event was a write
|
||||||
|
* request
|
||||||
|
* @return true if the request causing this event is a write request
|
||||||
|
*/
|
||||||
|
bool isWrite() const
|
||||||
|
{
|
||||||
|
return write;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the physical address of the request
|
||||||
|
* @return physical address of the request
|
||||||
|
*/
|
||||||
|
Addr getPaddr() const
|
||||||
|
{
|
||||||
|
return paddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this event comes from a cache miss
|
||||||
|
* @result true if this event comes from a cache miss
|
||||||
|
*/
|
||||||
|
bool isCacheMiss() const
|
||||||
|
{
|
||||||
|
return cacheMiss;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the associated data of the request triggering the event
|
||||||
|
* @param Byte ordering of the stored data
|
||||||
|
* @return the data
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline T
|
||||||
|
get(ByteOrder endian = TheISA::GuestByteOrder) const
|
||||||
|
{
|
||||||
|
if (data == nullptr) {
|
||||||
|
panic("PrefetchInfo::get called with a request with no data.");
|
||||||
|
}
|
||||||
|
switch (endian) {
|
||||||
|
case BigEndianByteOrder:
|
||||||
|
return betoh(*(T*)data);
|
||||||
|
|
||||||
|
case LittleEndianByteOrder:
|
||||||
|
return letoh(*(T*)data);
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic("Illegal byte order in PrefetchInfo::get()\n");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for equality
|
* Check for equality
|
||||||
* @param pfi PrefetchInfo to compare against
|
* @param pfi PrefetchInfo to compare against
|
||||||
@@ -157,9 +232,11 @@ class BasePrefetcher : public ClockedObject
|
|||||||
/**
|
/**
|
||||||
* Constructs a PrefetchInfo using a PacketPtr.
|
* Constructs a PrefetchInfo using a PacketPtr.
|
||||||
* @param pkt PacketPtr used to generate the PrefetchInfo
|
* @param pkt PacketPtr used to generate the PrefetchInfo
|
||||||
* @param addr the address value of the new object
|
* @param addr the address value of the new object, this address is
|
||||||
|
* used to train the prefetcher
|
||||||
|
* @param miss whether this event comes from a cache miss
|
||||||
*/
|
*/
|
||||||
PrefetchInfo(PacketPtr pkt, Addr addr);
|
PrefetchInfo(PacketPtr pkt, Addr addr, bool miss);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a PrefetchInfo using a new address value and
|
* Constructs a PrefetchInfo using a new address value and
|
||||||
@@ -168,6 +245,11 @@ class BasePrefetcher : public ClockedObject
|
|||||||
* @param addr the address value of the new object
|
* @param addr the address value of the new object
|
||||||
*/
|
*/
|
||||||
PrefetchInfo(PrefetchInfo const &pfi, Addr addr);
|
PrefetchInfo(PrefetchInfo const &pfi, Addr addr);
|
||||||
|
|
||||||
|
~PrefetchInfo()
|
||||||
|
{
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -209,8 +291,12 @@ class BasePrefetcher : public ClockedObject
|
|||||||
/** Use Virtual Addresses for prefetching */
|
/** Use Virtual Addresses for prefetching */
|
||||||
const bool useVirtualAddresses;
|
const bool useVirtualAddresses;
|
||||||
|
|
||||||
/** Determine if this access should be observed */
|
/**
|
||||||
bool observeAccess(const PacketPtr &pkt) const;
|
* 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
|
||||||
|
*/
|
||||||
|
bool observeAccess(const PacketPtr &pkt, bool miss) const;
|
||||||
|
|
||||||
/** Determine if address is in cache */
|
/** Determine if address is in cache */
|
||||||
bool inCache(Addr addr, bool is_secure) const;
|
bool inCache(Addr addr, bool is_secure) const;
|
||||||
@@ -275,8 +361,9 @@ class BasePrefetcher : public ClockedObject
|
|||||||
/**
|
/**
|
||||||
* Process a notification event from the ProbeListener.
|
* Process a notification event from the ProbeListener.
|
||||||
* @param pkt The memory request causing the event
|
* @param pkt The memory request causing the event
|
||||||
|
* @param miss whether this event comes from a cache miss
|
||||||
*/
|
*/
|
||||||
void probeNotify(const PacketPtr &pkt);
|
void probeNotify(const PacketPtr &pkt, bool miss);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a SimObject and a probe name to listen events from
|
* Add a SimObject and a probe name to listen events from
|
||||||
|
|||||||
Reference in New Issue
Block a user