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:
parent
afa2428eca
commit
435f4aec3d
2 changed files with 72 additions and 4 deletions
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue