mem: Add a simple snoop counter per bus

This patch adds a simple counter for both total messages and a histogram for
the fan-out of snoop messages.  The fan-out describes to how many ports snoops
had to be sent per incoming request / snoop-from-below.  Without any
cleverness, this usually means to either all, or all but the requesting port.
This commit is contained in:
Stephan Diestelhorst 2014-04-24 13:28:47 +01:00
parent fe98cb6be4
commit 7d488cc66f
2 changed files with 33 additions and 1 deletions

View file

@ -197,6 +197,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
if (is_express_snoop) { if (is_express_snoop) {
assert(success); assert(success);
snoopDataThroughBus += pkt_size; snoopDataThroughBus += pkt_size;
snoopsThroughBus++;
} else { } else {
// for normal requests, check if successful // for normal requests, check if successful
if (!success) { if (!success) {
@ -297,6 +298,7 @@ CoherentBus::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id)
// update stats here as we know the forwarding will succeed // update stats here as we know the forwarding will succeed
transDist[pkt->cmdToIndex()]++; transDist[pkt->cmdToIndex()]++;
snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0;
snoopsThroughBus++;
// we should only see express snoops from caches // we should only see express snoops from caches
assert(pkt->isExpressSnoop()); assert(pkt->isExpressSnoop());
@ -411,6 +413,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
// stats updates // stats updates
transDist[pkt_cmd]++; transDist[pkt_cmd]++;
snoopDataThroughBus += pkt_size; snoopDataThroughBus += pkt_size;
snoopsThroughBus++;
return true; return true;
} }
@ -425,6 +428,8 @@ CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
// snoops should only happen if the system isn't bypassing caches // snoops should only happen if the system isn't bypassing caches
assert(!system->bypassCaches()); assert(!system->bypassCaches());
unsigned fanout = 0;
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) { for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s; SlavePort *p = *s;
// we could have gotten this request from a snooping master // we could have gotten this request from a snooping master
@ -435,8 +440,12 @@ CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
p->getId() != exclude_slave_port_id) { p->getId() != exclude_slave_port_id) {
// cache is not allowed to refuse snoop // cache is not allowed to refuse snoop
p->sendTimingSnoopReq(pkt); p->sendTimingSnoopReq(pkt);
fanout++;
} }
} }
// Stats for fanout of this forward operation
snoopFanout.sample(fanout);
} }
void void
@ -503,6 +512,7 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id)
// add the request snoop data // add the request snoop data
snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0;
snoopsThroughBus++;
// forward to all snoopers // forward to all snoopers
std::pair<MemCmd, Tick> snoop_result = std::pair<MemCmd, Tick> snoop_result =
@ -514,8 +524,10 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id)
pkt->cmd = snoop_response_cmd; pkt->cmd = snoop_response_cmd;
// add the response snoop data // add the response snoop data
if (pkt->isResponse()) if (pkt->isResponse()) {
snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0;
snoopsThroughBus++;
}
// @todo: Not setting first-word time // @todo: Not setting first-word time
pkt->busLastWordDelay = snoop_response_latency; pkt->busLastWordDelay = snoop_response_latency;
@ -535,6 +547,8 @@ CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id)
// snoops should only happen if the system isn't bypassing caches // snoops should only happen if the system isn't bypassing caches
assert(!system->bypassCaches()); assert(!system->bypassCaches());
unsigned fanout = 0;
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) { for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s; SlavePort *p = *s;
// we could have gotten this request from a snooping master // we could have gotten this request from a snooping master
@ -544,6 +558,8 @@ CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id)
if (exclude_slave_port_id == InvalidPortID || if (exclude_slave_port_id == InvalidPortID ||
p->getId() != exclude_slave_port_id) { p->getId() != exclude_slave_port_id) {
Tick latency = p->sendAtomicSnoop(pkt); Tick latency = p->sendAtomicSnoop(pkt);
fanout++;
// in contrast to a functional access, we have to keep on // in contrast to a functional access, we have to keep on
// going as all snoopers must be updated even if we get a // going as all snoopers must be updated even if we get a
// response // response
@ -562,6 +578,9 @@ CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id)
} }
} }
// Stats for fanout
snoopFanout.sample(fanout);
// the packet is restored as part of the loop and any potential // the packet is restored as part of the loop and any potential
// snoop response is part of the returned pair // snoop response is part of the returned pair
return std::make_pair(snoop_response_cmd, snoop_response_latency); return std::make_pair(snoop_response_cmd, snoop_response_latency);
@ -667,6 +686,17 @@ CoherentBus::regStats()
.desc("Total snoop data (bytes)") .desc("Total snoop data (bytes)")
; ;
snoopsThroughBus
.name(name() + ".snoops_through_bus")
.desc("Total snoops (count)")
;
snoopFanout
.init(0, snoopPorts.size(), 1)
.name(name() + ".snoop_fanout")
.desc("Request fanout histogram")
;
throughput throughput
.name(name() + ".throughput") .name(name() + ".throughput")
.desc("Throughput (bytes/s)") .desc("Throughput (bytes/s)")

View file

@ -341,6 +341,8 @@ class CoherentBus : public BaseBus
Stats::Scalar dataThroughBus; Stats::Scalar dataThroughBus;
Stats::Scalar snoopDataThroughBus; Stats::Scalar snoopDataThroughBus;
Stats::Scalar snoopsThroughBus;
Stats::Distribution snoopFanout;
public: public: