summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Diestelhorst <stephan.diestelhorst@arm.com>2014-04-25 12:36:16 +0100
committerStephan Diestelhorst <stephan.diestelhorst@arm.com>2014-04-25 12:36:16 +0100
commit435f4aec3d87238a72a61f5b3eea5334d4c955e7 (patch)
tree504a9794eb130585834d1b00e13787eb62e529d6
parentafa2428eca9476cf63436dc138acafa36a1d408e (diff)
downloadgem5-435f4aec3d87238a72a61f5b3eea5334d4c955e7.tar.xz
mem: Add access statistics for the snoop filter
Adds a simple access counter for requests and snoops for the snoop filter and also classifies hits based on whether a single other holder existed or whether multiple shares held the line.
-rwxr-xr-xsrc/mem/snoop_filter.cc65
-rwxr-xr-xsrc/mem/snoop_filter.hh11
2 files changed, 72 insertions, 4 deletions
diff --git a/src/mem/snoop_filter.cc b/src/mem/snoop_filter.cc
index 1acfbef6c..a8a53362c 100755
--- a/src/mem/snoop_filter.cc
+++ b/src/mem/snoop_filter.cc
@@ -56,7 +56,20 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
SnoopMask req_port = portToMask(slave_port);
- SnoopItem& sf_item = cachedLocations[line_addr];
+ auto sf_it = cachedLocations.find(line_addr);
+ bool is_hit = (sf_it != cachedLocations.end());
+ // Create a new element through operator[] and modify in-place
+ SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr];
+ SnoopMask interested = sf_item.holder | sf_item.requested;
+
+ totRequests++;
+ if (is_hit) {
+ // Single bit set -> value is a power of two
+ if (isPow2(interested))
+ hitSingleRequests++;
+ else
+ hitMultiRequests++;
+ }
DPRINTF(SnoopFilter, "%s: SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
@@ -81,8 +94,7 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
}
- SnoopMask interested = (sf_item.holder | sf_item.requested) & ~req_port;
- return snoopSelected(maskToPortList(interested), lookupLatency);
+ return snoopSelected(maskToPortList(interested & ~req_port), lookupLatency);
}
void
@@ -141,12 +153,25 @@ SnoopFilter::lookupSnoop(const Packet* cpkt)
return snoopAll(lookupLatency);
Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
- SnoopItem& sf_item = cachedLocations[line_addr];
+ auto sf_it = cachedLocations.find(line_addr);
+ bool is_hit = (sf_it != cachedLocations.end());
+ // Create a new element through operator[] and modify in-place
+ SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr];
DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
SnoopMask interested = (sf_item.holder | sf_item.requested);
+
+ totSnoops++;
+ if (is_hit) {
+ // Single bit set -> value is a power of two
+ if (isPow2(interested))
+ hitSingleSnoops++;
+ else
+ hitMultiSnoops++;
+ }
+
assert(cpkt->isInvalidate() == cpkt->needsExclusive());
if (cpkt->isInvalidate() && !sf_item.requested) {
// Early clear of the holder, if no other request is currently going on
@@ -267,6 +292,38 @@ SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port)
__func__, sf_item.requested, sf_item.holder);
}
+void
+SnoopFilter::regStats()
+{
+ totRequests
+ .name(name() + ".tot_requests")
+ .desc("Total number of requests made to the snoop filter.");
+
+ hitSingleRequests
+ .name(name() + ".hit_single_requests")
+ .desc("Number of requests hitting in the snoop filter with a single "\
+ "holder of the requested data.");
+
+ hitMultiRequests
+ .name(name() + ".hit_multi_requests")
+ .desc("Number of requests hitting in the snoop filter with multiple "\
+ "(>1) holders of the requested data.");
+
+ totSnoops
+ .name(name() + ".tot_snoops")
+ .desc("Total number of snoops made to the snoop filter.");
+
+ hitSingleSnoops
+ .name(name() + ".hit_single_snoops")
+ .desc("Number of snoops hitting in the snoop filter with a single "\
+ "holder of the requested data.");
+
+ hitMultiSnoops
+ .name(name() + ".hit_multi_snoops")
+ .desc("Number of snoops hitting in the snoop filter with multiple "\
+ "(>1) holders of the requested data.");
+}
+
SnoopFilter *
SnoopFilterParams::create()
{
diff --git a/src/mem/snoop_filter.hh b/src/mem/snoop_filter.hh
index c1bb65dfc..88b534263 100755
--- a/src/mem/snoop_filter.hh
+++ b/src/mem/snoop_filter.hh
@@ -188,6 +188,8 @@ class SnoopFilter : public SimObject {
return std::make_pair(empty , latency);
}
+ virtual void regStats();
+
protected:
typedef uint64_t SnoopMask;
/**
@@ -227,6 +229,15 @@ class SnoopFilter : public SimObject {
const unsigned linesize;
/** Latency for doing a lookup in the filter */
const Cycles lookupLatency;
+
+ /** Statistics */
+ Stats::Scalar totRequests;
+ Stats::Scalar hitSingleRequests;
+ Stats::Scalar hitMultiRequests;
+
+ Stats::Scalar totSnoops;
+ Stats::Scalar hitSingleSnoops;
+ Stats::Scalar hitMultiSnoops;
};
inline SnoopFilter::SnoopMask