summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Bueno <javier.bueno@metempsy.com>2019-02-21 22:12:05 +0100
committerJavier Bueno Hedo <javier.bueno@metempsy.com>2019-03-10 21:49:56 +0000
commitb0d1643ddf849d5e9b68a2e6535fa1ef561eac92 (patch)
treef069b86f6994da34fdbad081dcd3e57baf9ee22a
parenta4686352714aa0d91b2d98b25a6f45b84262f97d (diff)
downloadgem5-b0d1643ddf849d5e9b68a2e6535fa1ef561eac92.tar.xz
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>
-rw-r--r--src/mem/cache/prefetch/base.cc47
-rw-r--r--src/mem/cache/prefetch/base.hh105
2 files changed, 126 insertions, 26 deletions
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 52f5d1a9a..366489227 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -56,16 +56,26 @@
#include "params/BasePrefetcher.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),
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)
: 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) {
parent.notifyFill(pkt);
} else {
- parent.probeNotify(pkt);
+ parent.probeNotify(pkt, miss);
}
}
@@ -114,13 +124,11 @@ BasePrefetcher::regStats()
}
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 read = pkt->isRead();
bool inv = pkt->isInvalidate();
- bool is_secure = pkt->isSecure();
if (pkt->req->isUncacheable()) 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 (onMiss) {
- return !inCache(addr, is_secure) &&
- !inMissQueue(addr, is_secure);
+ return miss;
}
return true;
@@ -193,25 +200,28 @@ BasePrefetcher::pageIthBlockAddress(Addr page, uint32_t blockIndex) const
}
void
-BasePrefetcher::probeNotify(const PacketPtr &pkt)
+BasePrefetcher::probeNotify(const PacketPtr &pkt, bool miss)
{
// 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->req->hasPaddr()) {
+ panic("Request must have a physical address");
+ }
if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
usefulPrefetches += 1;
}
// Verify this access type is observed by prefetcher
- if (observeAccess(pkt)) {
+ if (observeAccess(pkt, miss)) {
if (useVirtualAddresses && pkt->req->hasVaddr()) {
- PrefetchInfo pfi(pkt, pkt->req->getVaddr());
+ PrefetchInfo pfi(pkt, pkt->req->getVaddr(), miss);
notify(pkt, pfi);
- } else if (!useVirtualAddresses && pkt->req->hasPaddr()) {
- PrefetchInfo pfi(pkt, pkt->req->getPaddr());
+ } else if (!useVirtualAddresses) {
+ PrefetchInfo pfi(pkt, pkt->req->getPaddr(), miss);
notify(pkt, pfi);
}
}
@@ -227,10 +237,13 @@ BasePrefetcher::regProbeListeners()
*/
if (listeners.empty() && cache != nullptr) {
ProbeManager *pm(cache->getProbeManager());
- listeners.push_back(new PrefetchListener(*this, pm, "Miss"));
- listeners.push_back(new PrefetchListener(*this, pm, "Fill", true));
+ listeners.push_back(new PrefetchListener(*this, pm, "Miss", false,
+ true));
+ listeners.push_back(new PrefetchListener(*this, pm, "Fill", true,
+ false));
if (prefetchOnAccess) {
- listeners.push_back(new PrefetchListener(*this, pm, "Hit"));
+ listeners.push_back(new PrefetchListener(*this, pm, "Hit", false,
+ false));
}
}
}
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 4df8428c6..05895f223 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -51,10 +51,12 @@
#include <cstdint>
+#include "arch/isa_traits.hh"
#include "base/statistics.hh"
#include "base/types.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
+#include "sim/byteswap.hh"
#include "sim/clocked_object.hh"
#include "sim/probe/probe.hh"
@@ -67,13 +69,15 @@ class BasePrefetcher : public ClockedObject
{
public:
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),
- parent(_parent), isFill(_isFill) {}
+ parent(_parent), isFill(_isFill), miss(_miss) {}
void notify(const PacketPtr &pkt) override;
protected:
BasePrefetcher &parent;
- bool isFill;
+ const bool isFill;
+ const bool miss;
};
std::vector<PrefetchListener *> listeners;
@@ -85,7 +89,7 @@ class BasePrefetcher : public ClockedObject
* generate new prefetch requests.
*/
class PrefetchInfo {
- /** The address. */
+ /** The address used to train and generate prefetches */
Addr address;
/** The program counter that generated this address. */
Addr pc;
@@ -95,6 +99,16 @@ class BasePrefetcher : public ClockedObject
bool validPC;
/** Whether this address targets the secure memory space. */
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:
/**
@@ -144,6 +158,67 @@ class BasePrefetcher : public ClockedObject
}
/**
+ * 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
* @param pfi PrefetchInfo to compare against
* @return True if this object and the provided one are equal
@@ -157,9 +232,11 @@ class BasePrefetcher : public ClockedObject
/**
* Constructs a PrefetchInfo using a PacketPtr.
* @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
@@ -168,6 +245,11 @@ class BasePrefetcher : public ClockedObject
* @param addr the address value of the new object
*/
PrefetchInfo(PrefetchInfo const &pfi, Addr addr);
+
+ ~PrefetchInfo()
+ {
+ delete data;
+ }
};
protected:
@@ -209,8 +291,12 @@ class BasePrefetcher : public ClockedObject
/** Use Virtual Addresses for prefetching */
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 */
bool inCache(Addr addr, bool is_secure) const;
@@ -275,8 +361,9 @@ class BasePrefetcher : public ClockedObject
/**
* Process a notification event from the ProbeListener.
* @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