[gem5-dev] Change in gem5/gem5[develop]: mem-cache: accuracy and coverage stat for prefetchers

2021-07-09 Thread Nathanael Premillieu (Gerrit) via gem5-dev
Nathanael Premillieu has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/47603 )


Change subject: mem-cache: accuracy and coverage stat for prefetchers
..

mem-cache: accuracy and coverage stat for prefetchers

Add an accuracy and coverage stat for the prefetchers.
Accuracy is defined as the ratio of the number of prefetch
request that have been counted as useful over the number
of prefetch request issued.
Accuracy tells whether the prefetcher is producing useful
requests or not.
Coverage is defined as the ratio of of the number of prefetch
request that have been counted as useful over the number of
demand misses if there was no prefetch, which is counted as
the number of useful prefetch request plus the remaining
demand misses. Due to the way stats are defined in the cache,
I have to add a stat to count the number of remaining demand
misses directly in the prefetcher stat. Demand is defined
as being one of this request type: ReadReq, WriteReq,
WriteLineReq, ReadExReq, ReadCleanReq, ReadSharedReq.
Coverage tells what part of misses are covered by the prefetcher.

Change-Id: I3bb8838f87b42665fdd782889f6ba56ca2a802fc
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47603
Reviewed-by: Daniel Carvalho 
Maintainer: Daniel Carvalho 
Tested-by: kokoro 
---
M src/mem/cache/base.cc
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/packet.hh
4 files changed, 36 insertions(+), 3 deletions(-)

Approvals:
  Daniel Carvalho: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 32e132a..46eb3bf 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -308,6 +308,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
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 88d50b9..4c97588 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -119,6 +119,8 @@

 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"),
 ADD_STAT(pfUnused, statistics::units::Count::get(),
@@ -127,11 +129,22 @@
 "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")
+"state"),
+ADD_STAT(accuracy, statistics::units::Count::get(),
+"accuracy of the prefetcher"),
+ADD_STAT(coverage, statistics::units::Count::get(),
+"coverage brought by this prefetcher")
 {
-pfUnused.flags(statistics::nozero);
-}
+using namespace statistics;

+pfUnused.flags(nozero);
+
+accuracy.flags(total);
+accuracy = pfUseful / pfIssued;
+
+coverage.flags(total);
+coverage = pfUseful / (pfUseful + demandMshrMisses);
+}

 bool
 Base::observeAccess(const PacketPtr &pkt, bool miss) const
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index ddff8a2..0b19e01 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -328,6 +328,7 @@
 struct StatGroup : public statistics::Group
 {
 StatGroup(statistics::Group *parent);
+statistics::Scalar demandMshrMisses;
 statistics::Scalar pfIssued;
 /** The number of times a HW-prefetched block is evicted w/o
  * reference. */
@@ -337,6 +338,8 @@
 /** The number of times there is a hit on prefetch but cache block
  * is not in an usable state */
 statistics::Scalar pfUsefulButMiss;
+statistics::Formula accuracy;
+statistics::Formula coverage;
 } prefetchStats;

 /** Total prefetches issued */
@@ -373,6 +376,12 @@
 prefetchStats.pfUnused++;
 }

+void
+incrDemandMhsrMisses()
+{
+prefetchStats.demandMshrMisses++;
+}
+
 /**
  * Register probe points for this object.
  */
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 928a7dd..1283ac9 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -247,6 +247,14 @@
 bool isPrint() const{ return testCmdAttrib(IsPrint); }
 bool isFlush() const{ return testCmdAttrib(IsFlush); }

+bool
+isDemand() const
+{
+return (cmd == ReadReq || cmd == WriteReq ||
+cmd == WriteLineReq || cmd == ReadExReq ||
+   

[gem5-dev] Change in gem5/gem5[develop]: mem-cache: accuracy and coverage stat for prefetchers

2021-07-05 Thread Nathanael Premillieu (Gerrit) via gem5-dev
Nathanael Premillieu has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/47603 )



Change subject: mem-cache: accuracy and coverage stat for prefetchers
..

mem-cache: accuracy and coverage stat for prefetchers

Add an accuracy and coverage stat for the prefetchers.
Accuracy is defined as the ratio of the number of prefetch
request that have been counted as useful over the number
of prefetch request issued.
Accuracy tells whether the prefetcher is producing useful
requests or not.
Coverage is defined as the ratio of of the number of prefetch
request that have been counted as useful over the number of
demand misses if there was no prefetch, which is counted as
the number of useful prefetch request plus the remaining
demand misses. Due to the way stats are defined in the cache,
I have to add a stat to count the number of remaining demand
misses directly in the prefetcher stat. Demand is defined
as being one of this request type: ReadReq, WriteReq,
WriteLineReq, ReadExReq, ReadCleanReq, ReadSharedReq.
Coverage tells what part of misses are covered by the prefetcher.

Change-Id: I3bb8838f87b42665fdd782889f6ba56ca2a802fc
---
M src/mem/cache/base.cc
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/packet.hh
4 files changed, 36 insertions(+), 3 deletions(-)



diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 17895ce..3b7468f 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -308,6 +308,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
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 724cebf..d7ccbfd 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -119,6 +119,8 @@

 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"),
 ADD_STAT(pfUnused, statistics::units::Count::get(),
@@ -127,11 +129,22 @@
 "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")
+"state"),
+ADD_STAT(accuracy, statistics::units::Count::get(),
+"accuracy of the prefetcher"),
+ADD_STAT(coverage, statistics::units::Count::get(),
+"coverage brought by this prefetcher")
 {
-pfUnused.flags(statistics::nozero);
-}
+using namespace statistics;

+pfUnused.flags(nozero);
+
+accuracy.flags(total);
+accuracy = pfUseful / pfIssued;
+
+coverage.flags(total);
+coverage = pfUseful / (pfUseful + demandMshrMisses);
+}

 bool
 Base::observeAccess(const PacketPtr &pkt, bool miss) const
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 87b7f55..3bb5024 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -328,6 +328,7 @@
 struct StatGroup : public statistics::Group
 {
 StatGroup(statistics::Group *parent);
+statistics::Scalar demandMshrMisses;
 statistics::Scalar pfIssued;
 /** The number of times a HW-prefetched block is evicted w/o
  * reference. */
@@ -337,6 +338,8 @@
 /** The number of times there is a hit on prefetch but cache block
  * is not in an usable state */
 statistics::Scalar pfUsefulButMiss;
+statistics::Formula accuracy;
+statistics::Formula coverage;
 } prefetchStats;

 /** Total prefetches issued */
@@ -381,6 +384,12 @@
 prefetchStats.pfUseful++;
 }

+virtual void
+incrDemandMhsrMisses()
+{
+prefetchStats.demandMshrMisses++;
+}
+
 /**
  * Register probe points for this object.
  */
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 7ae6626..cf18d00 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -248,6 +248,14 @@
 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
 {
@@ -574,6 +582,7 @@

 bool isRead() const  { return cmd.isRead(); }
 bool isWrite() const { ret