Nathanael Premillieu has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/47200 )

Change subject: mem: add useful stats in prefetchers
......................................................................

mem: add useful stats in prefetchers

Added a global usefulPrefetches per cache level
Added accuracy and coverage for each prefetch.
To do so, the prefetch stats are tracking the number of demand misses
(I needed to add this stat in each prefetch for simplicity)
and a stat to track the number of useful prefetch.
An extra stat (pfUsefulButMiss) tracks the special case of
hit on prefetch but the block in not in an usable state.
For the moment, it assume one prefetcher per cache level,
as there is currently no support to track at the block level which
prefetcher has prefetched it.
Also add a DPRINTF for hit on prefetch

Change-Id: I652e059490885d2c835dfc406c423e95cba7166e
---
M src/mem/cache/base.cc
M src/mem/cache/base.hh
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/cache/prefetch/multi.cc
M src/mem/cache/prefetch/multi.hh
M src/mem/packet.hh
7 files changed, 80 insertions(+), 1 deletion(-)



diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 928c30b..0c5c13e 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -305,6 +305,8 @@
         // no MSHR
         assert(pkt->req->requestorId() < system->maxRequestors());
         stats.cmdStats(pkt).mshrMisses[pkt->req->requestorId()]++;
+        if (prefetcher && pkt->isDemand())
+            prefetcher->incrDemandMhsrMisses();

         if (pkt->isEviction() || pkt->cmd == MemCmd::WriteClean) {
             // We use forward_time here because there is an
@@ -377,6 +379,10 @@
         ppHit->notify(pkt);

         if (prefetcher && blk && blk->wasPrefetched()) {
+            stats.usefulPrefetches++;
+            prefetcher->prefetchUseful(blk);
+            DPRINTF(Cache, "Hit on prefetch for addr %#x on blk: %s\n",
+                    pkt->getAddr(), blk->print());
             blk->clearPrefetched();
         }

@@ -2123,6 +2129,9 @@
     ADD_STAT(avgBlocked, statistics::units::Rate<
                 statistics::units::Cycle, statistics::units::Count>::get(),
              "average number of cycles each access was blocked"),
+    ADD_STAT(usefulPrefetches, statistics::units::Count::get(),
+ "number of useful prefetches (prefetched block accessed at least "
+            "once)"),
     ADD_STAT(unusedPrefetches, statistics::units::Count::get(),
              "number of HardPF blocks evicted w/o reference"),
ADD_STAT(writebacks, statistics::units::Count::get(), "number of writebacks"),
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index b18284e..bf01152 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -1081,6 +1081,9 @@
         /** The average number of cycles blocked for each blocked cause. */
         statistics::Formula avgBlocked;

+        /** The number of times a HW-prefetch is useful. */
+        Stats::Scalar usefulPrefetches;
+
         /** The number of times a HW-prefetched block is evicted w/o
          * reference. */
         statistics::Scalar unusedPrefetches;
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 7536231..8c04033 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -116,11 +116,33 @@

 Base::StatGroup::StatGroup(statistics::Group *parent)
   : statistics::Group(parent),
+    ADD_STAT(demandMshrMisses, statistics::units::Count::get(),
+        "demands not covered by prefetchs"),
     ADD_STAT(pfIssued, statistics::units::Count::get(),
-        "number of hwpf issued")
+        "number of hwpf issued"),
+    ADD_STAT(pfUseful, statistics::units::Count::get(),
+        "number of useful prefetch"),
+    ADD_STAT(pfUsefulButMiss, statistics::units::Count::get(),
+        "number of hit on prefetch but cache block is not in an usable "
+        "state"),
+    ADD_STAT(accuracy, statistics::units::Count::get(),
+        "accuracy of the prefetcher"),
+    ADD_STAT(coverage, statistics::units::Count::get(),
+    "coverage brought by this prefetcher")
 {
 }

+void
+Base::StatGroup::regStats()
+{
+    using namespace Stats;
+
+    accuracy.flags(total);
+    accuracy = pfUseful / pfIssued;
+
+    coverage.flags(total);
+    coverage = pfUseful / (pfUseful + demandMshrMisses);
+}

 bool
 Base::observeAccess(const PacketPtr &pkt, bool miss) const
@@ -213,6 +235,10 @@

     if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
         usefulPrefetches += 1;
+        if (miss)
+            // This case happens when a demand hits on a prefetched line
+            // that's not in the requested coherency state.
+            prefetchStats.pfUsefulButMiss++;
     }

     // Verify this access type is observed by prefetcher
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 4e08034..c865da7 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -52,6 +52,7 @@
 #include "base/compiler.hh"
 #include "base/statistics.hh"
 #include "base/types.hh"
+#include "mem/cache/cache_blk.hh"
 #include "mem/packet.hh"
 #include "mem/request.hh"
 #include "sim/byteswap.hh"
@@ -324,7 +325,13 @@
     struct StatGroup : public statistics::Group
     {
         StatGroup(statistics::Group *parent);
+        void regStats() override;
+        statistics::Scalar demandMshrMisses;
         statistics::Scalar pfIssued;
+        statistics::Scalar pfUseful;
+        statistics::Scalar pfUsefulButMiss;
+        statistics::Formula accuracy;
+        statistics::Formula coverage;
     } prefetchStats;

     /** Total prefetches issued */
@@ -355,6 +362,15 @@

     virtual Tick nextPrefetchReadyTime() const = 0;

+    virtual void prefetchUseful(CacheBlk *blk)
+    {
+        assert(blk->wasPrefetched());
+        prefetchStats.pfUseful++;
+    }
+
+    virtual void incrDemandMhsrMisses() {
+        prefetchStats.demandMshrMisses++;
+    }

     /**
      * Register probe points for this object.
diff --git a/src/mem/cache/prefetch/multi.cc b/src/mem/cache/prefetch/multi.cc
index 74328cb..11b56e7 100644
--- a/src/mem/cache/prefetch/multi.cc
+++ b/src/mem/cache/prefetch/multi.cc
@@ -56,6 +56,20 @@
         pf->setCache(_cache);
 }

+void
+Multi::prefetchUseful(CacheBlk *blk)
+{
+    Base::prefetchUseful(blk);
+ // Until we can track which prefetcher sent the request, it is not possible
+    // to link the usefulness to a particular prefetcher
+}
+
+void
+Multi::incrDemandMhsrMisses()
+{
+    Base::incrDemandMhsrMisses();
+}
+
 Tick
 Multi::nextPrefetchReadyTime() const
 {
@@ -74,6 +88,7 @@
         if (pf->nextPrefetchReadyTime() <= curTick()) {
             PacketPtr pkt = pf->getPacket();
panic_if(!pkt, "Prefetcher is ready but didn't return a packet.");
+            prefetchStats.pfIssued++;
             return pkt;
         }
     }
diff --git a/src/mem/cache/prefetch/multi.hh b/src/mem/cache/prefetch/multi.hh
index 0206ffe..d8fa664 100644
--- a/src/mem/cache/prefetch/multi.hh
+++ b/src/mem/cache/prefetch/multi.hh
@@ -53,6 +53,8 @@

   public:
     void setCache(BaseCache *_cache) override;
+    void prefetchUseful(CacheBlk *blk) override;
+    void incrDemandMhsrMisses() override;
     PacketPtr getPacket() override;
     Tick nextPrefetchReadyTime() const override;

diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index d689bbe..d5bbc28 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -245,6 +245,13 @@
     bool isPrint() const        { return testCmdAttrib(IsPrint); }
     bool isFlush() const        { return testCmdAttrib(IsFlush); }

+    bool isDemand() const
+    {
+        return (cmd == ReadReq || cmd == WriteReq ||
+                cmd == WriteLineReq || cmd == ReadExReq ||
+                cmd == ReadCleanReq || cmd == ReadSharedReq);
+    }
+
     Command
     responseCommand() const
     {
@@ -571,6 +578,7 @@

     bool isRead() const              { return cmd.isRead(); }
     bool isWrite() const             { return cmd.isWrite(); }
+    bool isDemand() const            { return cmd.isDemand(); }
     bool isUpgrade()  const          { return cmd.isUpgrade(); }
     bool isRequest() const           { return cmd.isRequest(); }
     bool isResponse() const          { return cmd.isResponse(); }

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/47200
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I652e059490885d2c835dfc406c423e95cba7166e
Gerrit-Change-Number: 47200
Gerrit-PatchSet: 1
Gerrit-Owner: Nathanael Premillieu <nathanael.premill...@huawei.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to