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.
This commit is contained in:
Stephan Diestelhorst 2014-04-25 12:36:16 +01:00
parent afa2428eca
commit 435f4aec3d
2 changed files with 72 additions and 4 deletions

View file

@ -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()
{

View file

@ -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