summaryrefslogtreecommitdiff
path: root/src/mem/bus.cc
diff options
context:
space:
mode:
authorUri Wiener <uri.wiener@arm.com>2013-05-30 12:53:58 -0400
committerUri Wiener <uri.wiener@arm.com>2013-05-30 12:53:58 -0400
commit91f7b065a9b34ce0d3951001e30a9372d9b9dba9 (patch)
tree0dbe87473a59772269a82ecd14c9700ec0547424 /src/mem/bus.cc
parente1e73c5f395504647344d3eaa08a5300591896f8 (diff)
downloadgem5-91f7b065a9b34ce0d3951001e30a9372d9b9dba9.tar.xz
mem: Add basic stats to the buses
This patch adds a basic set of stats which are hard to impossible to implement using only communication monitors, and are needed for insight such as bus utilization, transactions through the bus etc. Stats added include throughput and transaction distribution, and also a two-dimensional vector capturing how many packets and how much data is exchanged between the masters and slaves connected to the bus.
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r--src/mem/bus.cc69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 41406e87a..8e74212e0 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -179,6 +179,9 @@ void BaseBus::Layer<PortClass>::occupyLayer(Tick until)
assert(until != 0);
bus.schedule(releaseEvent, until);
+ // account for the occupied ticks
+ occupancy += until - curTick();
+
DPRINTF(BaseBus, "The bus is now busy from tick %d to %d\n",
curTick(), until);
}
@@ -558,6 +561,52 @@ BaseBus::deviceBlockSize() const
return blockSize;
}
+void
+BaseBus::regStats()
+{
+ using namespace Stats;
+
+ transDist
+ .init(MemCmd::NUM_MEM_CMDS)
+ .name(name() + ".trans_dist")
+ .desc("Transaction distribution")
+ .flags(nozero);
+
+ // get the string representation of the commands
+ for (int i = 0; i < MemCmd::NUM_MEM_CMDS; i++) {
+ MemCmd cmd(i);
+ const std::string &cstr = cmd.toString();
+ transDist.subname(i, cstr);
+ }
+
+ pktCount
+ .init(slavePorts.size(), masterPorts.size())
+ .name(name() + ".pkt_count")
+ .desc("Packet count per connected master and slave (bytes)")
+ .flags(total | nozero | nonan);
+
+ totPktSize
+ .init(slavePorts.size(), masterPorts.size())
+ .name(name() + ".tot_pkt_size")
+ .desc("Cumulative packet size per connected master and slave (bytes)")
+ .flags(total | nozero | nonan);
+
+ // both the packet count and total size are two-dimensional
+ // vectors, indexed by slave port id and master port id, thus the
+ // neighbouring master and slave, they do not differentiate what
+ // came from the master and was forwarded to the slave (requests
+ // and snoop responses) and what came from the slave and was
+ // forwarded to the master (responses and snoop requests)
+ for (int i = 0; i < slavePorts.size(); i++) {
+ pktCount.subname(i, slavePorts[i]->getMasterPort().name());
+ totPktSize.subname(i, slavePorts[i]->getMasterPort().name());
+ for (int j = 0; j < masterPorts.size(); j++) {
+ pktCount.ysubname(j, masterPorts[j]->getSlavePort().name());
+ totPktSize.ysubname(j, masterPorts[j]->getSlavePort().name());
+ }
+ }
+}
+
template <typename PortClass>
unsigned int
BaseBus::Layer<PortClass>::drain(DrainManager *dm)
@@ -573,6 +622,26 @@ BaseBus::Layer<PortClass>::drain(DrainManager *dm)
return 0;
}
+template <typename PortClass>
+void
+BaseBus::Layer<PortClass>::regStats()
+{
+ using namespace Stats;
+
+ occupancy
+ .name(name() + ".occupancy")
+ .desc("Layer occupancy (ticks)")
+ .flags(nozero);
+
+ utilization
+ .name(name() + ".utilization")
+ .desc("Layer utilization (%)")
+ .precision(1)
+ .flags(nozero);
+
+ utilization = 100 * occupancy / simTicks;
+}
+
/**
* Bus layer template instantiations. Could be removed with _impl.hh
* file, but since there are only two given options (MasterPort and