mem-cache: Added extra information to PrefetchInfo
authorJavier Bueno <javier.bueno@metempsy.com>
Thu, 21 Feb 2019 21:12:05 +0000 (22:12 +0100)
committerJavier Bueno Hedo <javier.bueno@metempsy.com>
Sun, 10 Mar 2019 21:49:56 +0000 (21:49 +0000)
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>

src/mem/cache/prefetch/base.cc
src/mem/cache/prefetch/base.hh

index 52f5d1a9a0dd9768bb38fa4c7eec04a5be0cd099..3664892276ede32f60fdbb3f61db4915cae7ac5a 100644 (file)
 #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));
         }
     }
 }
index 4df8428c681dee956680fbafbaa2a5c6268361e5..05895f223151d45e9aeae5cc0dc0b2382fe39a69 100644 (file)
 
 #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:
         /**
@@ -143,6 +157,67 @@ class BasePrefetcher : public ClockedObject
             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
          * @param pfi PrefetchInfo to compare against
@@ -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