diff options
author | Stephan Diestelhorst <stephan.diestelhorst@arm.com> | 2014-04-24 13:28:47 +0100 |
---|---|---|
committer | Stephan Diestelhorst <stephan.diestelhorst@arm.com> | 2014-04-24 13:28:47 +0100 |
commit | 7d488cc66f77d8c6138f0117732ebc38758e814b (patch) | |
tree | 2a0ae00833e55eab273693a4d2d17ce16224c989 /src | |
parent | fe98cb6be471e8187658fea950bee0ecd5bf959c (diff) | |
download | gem5-7d488cc66f77d8c6138f0117732ebc38758e814b.tar.xz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/coherent_bus.cc | 32 | ||||
-rw-r--r-- | src/mem/coherent_bus.hh | 2 |
2 files changed, 33 insertions, 1 deletions
diff --git a/src/mem/coherent_bus.cc b/src/mem/coherent_bus.cc index 756d4c05c..f9d0a4968 100644 --- a/src/mem/coherent_bus.cc +++ b/src/mem/coherent_bus.cc @@ -197,6 +197,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id) if (is_express_snoop) { assert(success); snoopDataThroughBus += pkt_size; + snoopsThroughBus++; } else { // for normal requests, check if successful if (!success) { @@ -297,6 +298,7 @@ CoherentBus::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id) // update stats here as we know the forwarding will succeed transDist[pkt->cmdToIndex()]++; snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + snoopsThroughBus++; // we should only see express snoops from caches assert(pkt->isExpressSnoop()); @@ -411,6 +413,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) // stats updates transDist[pkt_cmd]++; snoopDataThroughBus += pkt_size; + snoopsThroughBus++; 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 assert(!system->bypassCaches()); + unsigned fanout = 0; + for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) { SlavePort *p = *s; // 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) { // cache is not allowed to refuse snoop p->sendTimingSnoopReq(pkt); + fanout++; } } + + // Stats for fanout of this forward operation + snoopFanout.sample(fanout); } void @@ -503,6 +512,7 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id) // add the request snoop data snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + snoopsThroughBus++; // forward to all snoopers std::pair<MemCmd, Tick> snoop_result = @@ -514,8 +524,10 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id) pkt->cmd = snoop_response_cmd; // add the response snoop data - if (pkt->isResponse()) + if (pkt->isResponse()) { snoopDataThroughBus += pkt->hasData() ? pkt->getSize() : 0; + snoopsThroughBus++; + } // @todo: Not setting first-word time 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 assert(!system->bypassCaches()); + unsigned fanout = 0; + for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) { SlavePort *p = *s; // 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 || p->getId() != exclude_slave_port_id) { Tick latency = p->sendAtomicSnoop(pkt); + fanout++; + // in contrast to a functional access, we have to keep on // going as all snoopers must be updated even if we get a // 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 // snoop response is part of the returned pair return std::make_pair(snoop_response_cmd, snoop_response_latency); @@ -667,6 +686,17 @@ CoherentBus::regStats() .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 .name(name() + ".throughput") .desc("Throughput (bytes/s)") diff --git a/src/mem/coherent_bus.hh b/src/mem/coherent_bus.hh index 8dde66d37..16ba92d26 100644 --- a/src/mem/coherent_bus.hh +++ b/src/mem/coherent_bus.hh @@ -341,6 +341,8 @@ class CoherentBus : public BaseBus Stats::Scalar dataThroughBus; Stats::Scalar snoopDataThroughBus; + Stats::Scalar snoopsThroughBus; + Stats::Distribution snoopFanout; public: |