diff --git a/src/mem/AbstractMemory.py b/src/mem/AbstractMemory.py index 57e47adcb1..f00e2868da 100644 --- a/src/mem/AbstractMemory.py +++ b/src/mem/AbstractMemory.py @@ -76,3 +76,12 @@ class AbstractMemory(ClockedObject): ) writeable = Param.Bool(True, "Allow writes to this memory") + + collect_stats = Param.Bool( + True, + "Collect statistics per requestor for " + "each type of access. Set this to `False` if " + "requestors may be unknown or when running " + "with multiple `System` objects without a " + "`SysBridge`.", + ) diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 9340f7e96f..461fd4c1fe 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -63,8 +63,8 @@ AbstractMemory::AbstractMemory(const Params &p) : MemBackdoor::Readable | MemBackdoor::Writeable : MemBackdoor::Readable)), confTableReported(p.conf_table_reported), inAddrMap(p.in_addr_map), - kvmMap(p.kvm_map), writeable(p.writeable), _system(NULL), - stats(*this) + kvmMap(p.kvm_map), writeable(p.writeable), collectStats(p.collect_stats), + _system(NULL), stats(*this) { panic_if(!range.valid() || !range.size(), "Memory range %s must be valid with non-zero size.", @@ -433,7 +433,9 @@ AbstractMemory::access(PacketPtr pkt) assert(!pkt->req->isInstFetch()); TRACE_PACKET("Read/Write"); - stats.numOther[pkt->req->requestorId()]++; + if (collectStats) { + stats.numOther[pkt->req->requestorId()]++; + } } } else if (pkt->isRead()) { assert(!pkt->isWrite()); @@ -447,10 +449,13 @@ AbstractMemory::access(PacketPtr pkt) pkt->setData(host_addr); } TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read"); - stats.numReads[pkt->req->requestorId()]++; - stats.bytesRead[pkt->req->requestorId()] += pkt->getSize(); - if (pkt->req->isInstFetch()) - stats.bytesInstRead[pkt->req->requestorId()] += pkt->getSize(); + if (collectStats) { + stats.numReads[pkt->req->requestorId()]++; + stats.bytesRead[pkt->req->requestorId()] += pkt->getSize(); + if (pkt->req->isInstFetch()) { + stats.bytesInstRead[pkt->req->requestorId()] += pkt->getSize(); + } + } } else if (pkt->isInvalidate() || pkt->isClean()) { assert(!pkt->isWrite()); // in a fastmem system invalidating and/or cleaning packets @@ -466,8 +471,10 @@ AbstractMemory::access(PacketPtr pkt) } assert(!pkt->req->isInstFetch()); TRACE_PACKET("Write"); - stats.numWrites[pkt->req->requestorId()]++; - stats.bytesWritten[pkt->req->requestorId()] += pkt->getSize(); + if (collectStats) { + stats.numWrites[pkt->req->requestorId()]++; + stats.bytesWritten[pkt->req->requestorId()] += pkt->getSize(); + } } } else { panic("Unexpected packet %s", pkt->print()); diff --git a/src/mem/abstract_mem.hh b/src/mem/abstract_mem.hh index 7f12487421..8c85f4503e 100644 --- a/src/mem/abstract_mem.hh +++ b/src/mem/abstract_mem.hh @@ -132,6 +132,9 @@ class AbstractMemory : public ClockedObject // Are writes allowed to this memory const bool writeable; + // Should collect traffic statistics + const bool collectStats; + std::list lockedAddrList; // helper function for checkLockedAddrs(): we really want to