diff -r 4b617b62969a -r 3e1a0e92a25c src/mem/snoop_filter.hh --- a/src/mem/snoop_filter.hh Wed Sep 10 08:55:40 2014 +0100 +++ b/src/mem/snoop_filter.hh Fri Apr 25 12:36:16 2014 +0100 @@ -188,6 +188,8 @@ return std::make_pair(empty , latency); } + virtual void regStats(); + protected: typedef uint64_t SnoopMask; /** @@ -227,6 +229,15 @@ 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 diff -r 4b617b62969a -r 3e1a0e92a25c src/mem/snoop_filter.cc --- a/src/mem/snoop_filter.cc Wed Sep 10 08:55:40 2014 +0100 +++ b/src/mem/snoop_filter.cc Fri Apr 25 12:36:16 2014 +0100 @@ -56,7 +56,20 @@ 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 @@ 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 @@ 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 @@ __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() {