comm_monitor.cc revision 10309
111784Sarthur.perais@inria.fr/* 211784Sarthur.perais@inria.fr * Copyright (c) 2012-2013 ARM Limited 311784Sarthur.perais@inria.fr * All rights reserved 411784Sarthur.perais@inria.fr * 511784Sarthur.perais@inria.fr * The license below extends only to copyright in the software and shall 611784Sarthur.perais@inria.fr * not be construed as granting a license to any other intellectual 711784Sarthur.perais@inria.fr * property including but not limited to intellectual property relating 811784Sarthur.perais@inria.fr * to a hardware implementation of the functionality of the software 911784Sarthur.perais@inria.fr * licensed hereunder. You may use the software subject to the license 1011784Sarthur.perais@inria.fr * terms below provided that you ensure that this notice is replicated 1111784Sarthur.perais@inria.fr * unmodified and in its entirety in all distributions of the software, 1211784Sarthur.perais@inria.fr * modified or unmodified, in source code or in binary form. 1311784Sarthur.perais@inria.fr * 1411784Sarthur.perais@inria.fr * Redistribution and use in source and binary forms, with or without 1511784Sarthur.perais@inria.fr * modification, are permitted provided that the following conditions are 1611784Sarthur.perais@inria.fr * met: redistributions of source code must retain the above copyright 1711784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer; 1811784Sarthur.perais@inria.fr * redistributions in binary form must reproduce the above copyright 1911784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer in the 2011784Sarthur.perais@inria.fr * documentation and/or other materials provided with the distribution; 2111784Sarthur.perais@inria.fr * neither the name of the copyright holders nor the names of its 2211784Sarthur.perais@inria.fr * contributors may be used to endorse or promote products derived from 2311784Sarthur.perais@inria.fr * this software without specific prior written permission. 2411784Sarthur.perais@inria.fr * 2511784Sarthur.perais@inria.fr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2611784Sarthur.perais@inria.fr * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2711784Sarthur.perais@inria.fr * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2811784Sarthur.perais@inria.fr * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2911784Sarthur.perais@inria.fr * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3011784Sarthur.perais@inria.fr * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3111784Sarthur.perais@inria.fr * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3211784Sarthur.perais@inria.fr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3311784Sarthur.perais@inria.fr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3411784Sarthur.perais@inria.fr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3511784Sarthur.perais@inria.fr * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3611784Sarthur.perais@inria.fr * 3711784Sarthur.perais@inria.fr * Authors: Thomas Grass 3811784Sarthur.perais@inria.fr * Andreas Hansson 3911784Sarthur.perais@inria.fr */ 4011784Sarthur.perais@inria.fr 4111784Sarthur.perais@inria.fr#include "base/callback.hh" 4211784Sarthur.perais@inria.fr#include "base/output.hh" 4311784Sarthur.perais@inria.fr#include "base/trace.hh" 4412334Sgabeblack@google.com#include "debug/CommMonitor.hh" 4511784Sarthur.perais@inria.fr#include "mem/comm_monitor.hh" 4611784Sarthur.perais@inria.fr#include "proto/packet.pb.h" 4711784Sarthur.perais@inria.fr#include "sim/stats.hh" 4811784Sarthur.perais@inria.fr 4911784Sarthur.perais@inria.frCommMonitor::CommMonitor(Params* params) 5011784Sarthur.perais@inria.fr : MemObject(params), 5111784Sarthur.perais@inria.fr masterPort(name() + "-master", *this), 5211784Sarthur.perais@inria.fr slavePort(name() + "-slave", *this), 5313420Spau.cabre@metempsy.com samplePeriodicEvent(this), 5411784Sarthur.perais@inria.fr samplePeriodTicks(params->sample_period), 5511784Sarthur.perais@inria.fr readAddrMask(params->read_addr_mask), 5611784Sarthur.perais@inria.fr writeAddrMask(params->write_addr_mask), 5711784Sarthur.perais@inria.fr stats(params), 5811784Sarthur.perais@inria.fr traceStream(NULL), 5911784Sarthur.perais@inria.fr system(params->system) 6011784Sarthur.perais@inria.fr{ 6111784Sarthur.perais@inria.fr // If we are using a trace file, then open the file 6213442Spau.cabre@metempsy.com if (params->trace_enable) { 6313442Spau.cabre@metempsy.com std::string filename; 6413442Spau.cabre@metempsy.com if (params->trace_file != "") { 6513442Spau.cabre@metempsy.com // If the trace file is not specified as an absolute path, 6613442Spau.cabre@metempsy.com // append the current simulation output directory 6713442Spau.cabre@metempsy.com filename = simout.resolve(params->trace_file); 6813442Spau.cabre@metempsy.com 6911784Sarthur.perais@inria.fr std::string suffix = ".gz"; 7011784Sarthur.perais@inria.fr // If trace_compress has been set, check the suffix. Append 7113442Spau.cabre@metempsy.com // accordingly. 7213442Spau.cabre@metempsy.com if (params->trace_compress && 7313442Spau.cabre@metempsy.com filename.compare(filename.size() - suffix.size(), suffix.size(), 7413442Spau.cabre@metempsy.com suffix) != 0) 7513442Spau.cabre@metempsy.com filename = filename + suffix; 7611784Sarthur.perais@inria.fr } else { 7711784Sarthur.perais@inria.fr // Generate a filename from the name of the SimObject. Append .trc 7811784Sarthur.perais@inria.fr // and .gz if we want compression enabled. 7911784Sarthur.perais@inria.fr filename = simout.resolve(name() + ".trc" + 8011784Sarthur.perais@inria.fr (params->trace_compress ? ".gz" : "")); 8111784Sarthur.perais@inria.fr } 8211784Sarthur.perais@inria.fr 8311784Sarthur.perais@inria.fr traceStream = new ProtoOutputStream(filename); 8411784Sarthur.perais@inria.fr 8511784Sarthur.perais@inria.fr // Create a protobuf message for the header and write it to 8611784Sarthur.perais@inria.fr // the stream 8711784Sarthur.perais@inria.fr ProtoMessage::PacketHeader header_msg; 8811784Sarthur.perais@inria.fr header_msg.set_obj_id(name()); 8911784Sarthur.perais@inria.fr header_msg.set_tick_freq(SimClock::Frequency); 9011784Sarthur.perais@inria.fr traceStream->write(header_msg); 9111784Sarthur.perais@inria.fr 9211784Sarthur.perais@inria.fr // Register a callback to compensate for the destructor not 9311784Sarthur.perais@inria.fr // being called. The callback forces the stream to flush and 9411784Sarthur.perais@inria.fr // closes the output file. 9511784Sarthur.perais@inria.fr Callback* cb = new MakeCallback<CommMonitor, 9611784Sarthur.perais@inria.fr &CommMonitor::closeStreams>(this); 9711784Sarthur.perais@inria.fr registerExitCallback(cb); 9811784Sarthur.perais@inria.fr } 9911784Sarthur.perais@inria.fr 10011784Sarthur.perais@inria.fr // keep track of the sample period both in ticks and absolute time 10111784Sarthur.perais@inria.fr samplePeriod.setTick(params->sample_period); 10211784Sarthur.perais@inria.fr 10311784Sarthur.perais@inria.fr DPRINTF(CommMonitor, 10411784Sarthur.perais@inria.fr "Created monitor %s with sample period %d ticks (%f ms)\n", 10511784Sarthur.perais@inria.fr name(), samplePeriodTicks, samplePeriod.msec()); 10611784Sarthur.perais@inria.fr} 10711784Sarthur.perais@inria.fr 10811784Sarthur.perais@inria.frvoid 10911784Sarthur.perais@inria.frCommMonitor::closeStreams() 11011784Sarthur.perais@inria.fr{ 11111784Sarthur.perais@inria.fr if (traceStream != NULL) 11211784Sarthur.perais@inria.fr delete traceStream; 11311784Sarthur.perais@inria.fr} 11411784Sarthur.perais@inria.fr 11511784Sarthur.perais@inria.frCommMonitor* 11611784Sarthur.perais@inria.frCommMonitorParams::create() 11711784Sarthur.perais@inria.fr{ 11811784Sarthur.perais@inria.fr return new CommMonitor(this); 11911784Sarthur.perais@inria.fr} 12011784Sarthur.perais@inria.fr 12111784Sarthur.perais@inria.frvoid 12211784Sarthur.perais@inria.frCommMonitor::init() 12311784Sarthur.perais@inria.fr{ 12411784Sarthur.perais@inria.fr // make sure both sides of the monitor are connected 12511784Sarthur.perais@inria.fr if (!slavePort.isConnected() || !masterPort.isConnected()) 12611784Sarthur.perais@inria.fr fatal("Communication monitor is not connected on both sides.\n"); 12711784Sarthur.perais@inria.fr 12811784Sarthur.perais@inria.fr if (traceStream != NULL) { 12911784Sarthur.perais@inria.fr // Check the memory mode. We only record something when in 13011784Sarthur.perais@inria.fr // timing mode. Warn accordingly. 13111784Sarthur.perais@inria.fr if (!system->isTimingMode()) 13211784Sarthur.perais@inria.fr warn("%s: Not in timing mode. No trace will be recorded.", name()); 13311784Sarthur.perais@inria.fr } 13411784Sarthur.perais@inria.fr} 13511784Sarthur.perais@inria.fr 13611784Sarthur.perais@inria.frBaseMasterPort& 13711784Sarthur.perais@inria.frCommMonitor::getMasterPort(const std::string& if_name, PortID idx) 13813420Spau.cabre@metempsy.com{ 13913420Spau.cabre@metempsy.com if (if_name == "master") { 14013420Spau.cabre@metempsy.com return masterPort; 14113420Spau.cabre@metempsy.com } else { 14213420Spau.cabre@metempsy.com return MemObject::getMasterPort(if_name, idx); 14311784Sarthur.perais@inria.fr } 14411784Sarthur.perais@inria.fr} 14511784Sarthur.perais@inria.fr 14611784Sarthur.perais@inria.frBaseSlavePort& 14711784Sarthur.perais@inria.frCommMonitor::getSlavePort(const std::string& if_name, PortID idx) 14811784Sarthur.perais@inria.fr{ 14911784Sarthur.perais@inria.fr if (if_name == "slave") { 15011784Sarthur.perais@inria.fr return slavePort; 15111784Sarthur.perais@inria.fr } else { 15211784Sarthur.perais@inria.fr return MemObject::getSlavePort(if_name, idx); 15311784Sarthur.perais@inria.fr } 15411784Sarthur.perais@inria.fr} 15511784Sarthur.perais@inria.fr 15611784Sarthur.perais@inria.frvoid 15711784Sarthur.perais@inria.frCommMonitor::recvFunctional(PacketPtr pkt) 15813413Spau.cabre@metempsy.com{ 15911784Sarthur.perais@inria.fr masterPort.sendFunctional(pkt); 16011784Sarthur.perais@inria.fr} 16111784Sarthur.perais@inria.fr 16211784Sarthur.perais@inria.frvoid 16311784Sarthur.perais@inria.frCommMonitor::recvFunctionalSnoop(PacketPtr pkt) 16413413Spau.cabre@metempsy.com{ 16513413Spau.cabre@metempsy.com slavePort.sendFunctionalSnoop(pkt); 16611784Sarthur.perais@inria.fr} 16711784Sarthur.perais@inria.fr 16811784Sarthur.perais@inria.frTick 16911784Sarthur.perais@inria.frCommMonitor::recvAtomic(PacketPtr pkt) 17011784Sarthur.perais@inria.fr{ 17111784Sarthur.perais@inria.fr return masterPort.sendAtomic(pkt); 17211784Sarthur.perais@inria.fr} 17311784Sarthur.perais@inria.fr 17411784Sarthur.perais@inria.frTick 17511784Sarthur.perais@inria.frCommMonitor::recvAtomicSnoop(PacketPtr pkt) 17611784Sarthur.perais@inria.fr{ 17711784Sarthur.perais@inria.fr return slavePort.sendAtomicSnoop(pkt); 17811784Sarthur.perais@inria.fr} 17911784Sarthur.perais@inria.fr 18011784Sarthur.perais@inria.frbool 18111784Sarthur.perais@inria.frCommMonitor::recvTimingReq(PacketPtr pkt) 18211784Sarthur.perais@inria.fr{ 18311784Sarthur.perais@inria.fr // should always see a request 18411784Sarthur.perais@inria.fr assert(pkt->isRequest()); 18511784Sarthur.perais@inria.fr 18611784Sarthur.perais@inria.fr // Store relevant fields of packet, because packet may be modified 18711784Sarthur.perais@inria.fr // or even deleted when sendTiming() is called. 18811784Sarthur.perais@inria.fr bool is_read = pkt->isRead(); 18911784Sarthur.perais@inria.fr bool is_write = pkt->isWrite(); 19011784Sarthur.perais@inria.fr int cmd = pkt->cmdToIndex(); 19111784Sarthur.perais@inria.fr Request::FlagsType req_flags = pkt->req->getFlags(); 19213413Spau.cabre@metempsy.com unsigned size = pkt->getSize(); 19313413Spau.cabre@metempsy.com Addr addr = pkt->getAddr(); 19411784Sarthur.perais@inria.fr bool expects_response = pkt->needsResponse() && !pkt->memInhibitAsserted(); 19511784Sarthur.perais@inria.fr 19611784Sarthur.perais@inria.fr // If a cache miss is served by a cache, a monitor near the memory 19711784Sarthur.perais@inria.fr // would see a request which needs a response, but this response 19811784Sarthur.perais@inria.fr // would be inhibited and not come back from the memory. Therefore 19911784Sarthur.perais@inria.fr // we additionally have to check the inhibit flag. 20011784Sarthur.perais@inria.fr if (expects_response && !stats.disableLatencyHists) { 20111784Sarthur.perais@inria.fr pkt->pushSenderState(new CommMonitorSenderState(curTick())); 20211784Sarthur.perais@inria.fr } 20311784Sarthur.perais@inria.fr 20411784Sarthur.perais@inria.fr // Attempt to send the packet (always succeeds for inhibited 20513413Spau.cabre@metempsy.com // packets) 20613413Spau.cabre@metempsy.com bool successful = masterPort.sendTimingReq(pkt); 20713413Spau.cabre@metempsy.com 20811784Sarthur.perais@inria.fr // If not successful, restore the sender state 20911784Sarthur.perais@inria.fr if (!successful && expects_response && !stats.disableLatencyHists) { 21011784Sarthur.perais@inria.fr delete pkt->popSenderState(); 21111784Sarthur.perais@inria.fr } 21211784Sarthur.perais@inria.fr 21311784Sarthur.perais@inria.fr if (successful && traceStream != NULL) { 21411784Sarthur.perais@inria.fr // Create a protobuf message representing the 21511784Sarthur.perais@inria.fr // packet. Currently we do not preserve the flags in the 21611784Sarthur.perais@inria.fr // trace. 21711784Sarthur.perais@inria.fr ProtoMessage::Packet pkt_msg; 21811784Sarthur.perais@inria.fr pkt_msg.set_tick(curTick()); 21911784Sarthur.perais@inria.fr pkt_msg.set_cmd(cmd); 22011784Sarthur.perais@inria.fr pkt_msg.set_flags(req_flags); 22111784Sarthur.perais@inria.fr pkt_msg.set_addr(addr); 22211784Sarthur.perais@inria.fr pkt_msg.set_size(size); 22311784Sarthur.perais@inria.fr 22411784Sarthur.perais@inria.fr traceStream->write(pkt_msg); 22511784Sarthur.perais@inria.fr } 22611784Sarthur.perais@inria.fr 22713442Spau.cabre@metempsy.com if (successful && is_read) { 22813442Spau.cabre@metempsy.com DPRINTF(CommMonitor, "Forwarded read request\n"); 22913442Spau.cabre@metempsy.com 23013442Spau.cabre@metempsy.com // Increment number of observed read transactions 23113442Spau.cabre@metempsy.com if (!stats.disableTransactionHists) { 23213442Spau.cabre@metempsy.com ++stats.readTrans; 23313442Spau.cabre@metempsy.com } 23413442Spau.cabre@metempsy.com 23513442Spau.cabre@metempsy.com // Get sample of burst length 23613442Spau.cabre@metempsy.com if (!stats.disableBurstLengthHists) { 23713442Spau.cabre@metempsy.com stats.readBurstLengthHist.sample(size); 23813442Spau.cabre@metempsy.com } 23913442Spau.cabre@metempsy.com 24013442Spau.cabre@metempsy.com // Sample the masked address 24111784Sarthur.perais@inria.fr if (!stats.disableAddrDists) { 24211784Sarthur.perais@inria.fr stats.readAddrDist.sample(addr & readAddrMask); 24311784Sarthur.perais@inria.fr } 24411784Sarthur.perais@inria.fr 24513420Spau.cabre@metempsy.com // If it needs a response increment number of outstanding read 24611784Sarthur.perais@inria.fr // requests 24711784Sarthur.perais@inria.fr if (!stats.disableOutstandingHists && expects_response) { 24811784Sarthur.perais@inria.fr ++stats.outstandingReadReqs; 24913420Spau.cabre@metempsy.com } 25013420Spau.cabre@metempsy.com 25111784Sarthur.perais@inria.fr if (!stats.disableITTDists) { 25211784Sarthur.perais@inria.fr // Sample value of read-read inter transaction time 25311784Sarthur.perais@inria.fr if (stats.timeOfLastRead != 0) { 25413420Spau.cabre@metempsy.com stats.ittReadRead.sample(curTick() - stats.timeOfLastRead); 25513420Spau.cabre@metempsy.com } 25611784Sarthur.perais@inria.fr stats.timeOfLastRead = curTick(); 25711784Sarthur.perais@inria.fr 25811784Sarthur.perais@inria.fr // Sample value of req-req inter transaction time 25911784Sarthur.perais@inria.fr if (stats.timeOfLastReq != 0) { 26011784Sarthur.perais@inria.fr stats.ittReqReq.sample(curTick() - stats.timeOfLastReq); 26111784Sarthur.perais@inria.fr } 26213420Spau.cabre@metempsy.com stats.timeOfLastReq = curTick(); 26313420Spau.cabre@metempsy.com } 26413420Spau.cabre@metempsy.com } else if (successful && is_write) { 26513420Spau.cabre@metempsy.com DPRINTF(CommMonitor, "Forwarded write request\n"); 26613420Spau.cabre@metempsy.com 26711784Sarthur.perais@inria.fr // Same as for reads 26811784Sarthur.perais@inria.fr if (!stats.disableTransactionHists) { 26911784Sarthur.perais@inria.fr ++stats.writeTrans; 27011784Sarthur.perais@inria.fr } 27111784Sarthur.perais@inria.fr 27211784Sarthur.perais@inria.fr if (!stats.disableBurstLengthHists) { 27311784Sarthur.perais@inria.fr stats.writeBurstLengthHist.sample(size); 27411784Sarthur.perais@inria.fr } 27511784Sarthur.perais@inria.fr 27611784Sarthur.perais@inria.fr // Update the bandwidth stats on the request 27713442Spau.cabre@metempsy.com if (!stats.disableBandwidthHists) { 27811784Sarthur.perais@inria.fr stats.writtenBytes += size; 27911784Sarthur.perais@inria.fr stats.totalWrittenBytes += size; 28011784Sarthur.perais@inria.fr } 28111784Sarthur.perais@inria.fr 28213442Spau.cabre@metempsy.com // Sample the masked write address 28313442Spau.cabre@metempsy.com if (!stats.disableAddrDists) { 28411784Sarthur.perais@inria.fr stats.writeAddrDist.sample(addr & writeAddrMask); 28511784Sarthur.perais@inria.fr } 28611784Sarthur.perais@inria.fr 28711784Sarthur.perais@inria.fr if (!stats.disableOutstandingHists && expects_response) { 28811784Sarthur.perais@inria.fr ++stats.outstandingWriteReqs; 28911784Sarthur.perais@inria.fr } 29011784Sarthur.perais@inria.fr 29111784Sarthur.perais@inria.fr if (!stats.disableITTDists) { 29211784Sarthur.perais@inria.fr // Sample value of write-to-write inter transaction time 29311784Sarthur.perais@inria.fr if (stats.timeOfLastWrite != 0) { 29411784Sarthur.perais@inria.fr stats.ittWriteWrite.sample(curTick() - stats.timeOfLastWrite); 29511784Sarthur.perais@inria.fr } 29611784Sarthur.perais@inria.fr stats.timeOfLastWrite = curTick(); 29711784Sarthur.perais@inria.fr 29811784Sarthur.perais@inria.fr // Sample value of req-to-req inter transaction time 29911784Sarthur.perais@inria.fr if (stats.timeOfLastReq != 0) { 30011784Sarthur.perais@inria.fr stats.ittReqReq.sample(curTick() - stats.timeOfLastReq); 30111784Sarthur.perais@inria.fr } 30211784Sarthur.perais@inria.fr stats.timeOfLastReq = curTick(); 30311784Sarthur.perais@inria.fr } 30413442Spau.cabre@metempsy.com } else if (successful) { 30513442Spau.cabre@metempsy.com DPRINTF(CommMonitor, "Forwarded non read/write request\n"); 30611784Sarthur.perais@inria.fr } 30711784Sarthur.perais@inria.fr 30811784Sarthur.perais@inria.fr return successful; 30911784Sarthur.perais@inria.fr} 31011784Sarthur.perais@inria.fr 31111784Sarthur.perais@inria.frbool 31211784Sarthur.perais@inria.frCommMonitor::recvTimingResp(PacketPtr pkt) 31311784Sarthur.perais@inria.fr{ 31411784Sarthur.perais@inria.fr // should always see responses 31511784Sarthur.perais@inria.fr assert(pkt->isResponse()); 31611784Sarthur.perais@inria.fr 31711784Sarthur.perais@inria.fr // Store relevant fields of packet, because packet may be modified 31811784Sarthur.perais@inria.fr // or even deleted when sendTiming() is called. 31911784Sarthur.perais@inria.fr bool is_read = pkt->isRead(); 32011784Sarthur.perais@inria.fr bool is_write = pkt->isWrite(); 32111784Sarthur.perais@inria.fr unsigned size = pkt->getSize(); 32211784Sarthur.perais@inria.fr Tick latency = 0; 32311784Sarthur.perais@inria.fr CommMonitorSenderState* received_state = 32411784Sarthur.perais@inria.fr dynamic_cast<CommMonitorSenderState*>(pkt->senderState); 32511784Sarthur.perais@inria.fr 32613442Spau.cabre@metempsy.com if (!stats.disableLatencyHists) { 32711784Sarthur.perais@inria.fr // Restore initial sender state 32811784Sarthur.perais@inria.fr if (received_state == NULL) 32911784Sarthur.perais@inria.fr panic("Monitor got a response without monitor sender state\n"); 33013442Spau.cabre@metempsy.com 33113442Spau.cabre@metempsy.com // Restore the sate 33211784Sarthur.perais@inria.fr pkt->senderState = received_state->predecessor; 33311784Sarthur.perais@inria.fr } 33411784Sarthur.perais@inria.fr 33511784Sarthur.perais@inria.fr // Attempt to send the packet 33611784Sarthur.perais@inria.fr bool successful = slavePort.sendTimingResp(pkt); 33711784Sarthur.perais@inria.fr 33811784Sarthur.perais@inria.fr if (!stats.disableLatencyHists) { 33911784Sarthur.perais@inria.fr // If packet successfully send, sample value of latency, 34011784Sarthur.perais@inria.fr // afterwards delete sender state, otherwise restore state 34111784Sarthur.perais@inria.fr if (successful) { 34211784Sarthur.perais@inria.fr latency = curTick() - received_state->transmitTime; 34311784Sarthur.perais@inria.fr DPRINTF(CommMonitor, "Latency: %d\n", latency); 34411784Sarthur.perais@inria.fr delete received_state; 34511784Sarthur.perais@inria.fr } else { 34613442Spau.cabre@metempsy.com // Don't delete anything and let the packet look like we 34713442Spau.cabre@metempsy.com // did not touch it 34811784Sarthur.perais@inria.fr pkt->senderState = received_state; 34911784Sarthur.perais@inria.fr } 35011784Sarthur.perais@inria.fr } 35111784Sarthur.perais@inria.fr 35211784Sarthur.perais@inria.fr if (successful && is_read) { 35311784Sarthur.perais@inria.fr // Decrement number of outstanding read requests 35411784Sarthur.perais@inria.fr DPRINTF(CommMonitor, "Received read response\n"); 35511784Sarthur.perais@inria.fr if (!stats.disableOutstandingHists) { 35611784Sarthur.perais@inria.fr assert(stats.outstandingReadReqs != 0); 35711784Sarthur.perais@inria.fr --stats.outstandingReadReqs; 35811784Sarthur.perais@inria.fr } 35911784Sarthur.perais@inria.fr 36011784Sarthur.perais@inria.fr if (!stats.disableLatencyHists) { 36111784Sarthur.perais@inria.fr stats.readLatencyHist.sample(latency); 36211784Sarthur.perais@inria.fr } 36311784Sarthur.perais@inria.fr 36411784Sarthur.perais@inria.fr // Update the bandwidth stats based on responses for reads 36511784Sarthur.perais@inria.fr if (!stats.disableBandwidthHists) { 36611784Sarthur.perais@inria.fr stats.readBytes += size; 36711784Sarthur.perais@inria.fr stats.totalReadBytes += size; 36811784Sarthur.perais@inria.fr } 36911784Sarthur.perais@inria.fr 37011784Sarthur.perais@inria.fr } else if (successful && is_write) { 37111784Sarthur.perais@inria.fr // Decrement number of outstanding write requests 37211784Sarthur.perais@inria.fr DPRINTF(CommMonitor, "Received write response\n"); 37311784Sarthur.perais@inria.fr if (!stats.disableOutstandingHists) { 37411784Sarthur.perais@inria.fr assert(stats.outstandingWriteReqs != 0); 37511784Sarthur.perais@inria.fr --stats.outstandingWriteReqs; 37611784Sarthur.perais@inria.fr } 37711784Sarthur.perais@inria.fr 37811784Sarthur.perais@inria.fr if (!stats.disableLatencyHists) { 37911784Sarthur.perais@inria.fr stats.writeLatencyHist.sample(latency); 38011784Sarthur.perais@inria.fr } 38111784Sarthur.perais@inria.fr } else if (successful) { 38211784Sarthur.perais@inria.fr DPRINTF(CommMonitor, "Received non read/write response\n"); 38311784Sarthur.perais@inria.fr } 38411784Sarthur.perais@inria.fr return successful; 38513442Spau.cabre@metempsy.com} 38611784Sarthur.perais@inria.fr 38711784Sarthur.perais@inria.frvoid 38811784Sarthur.perais@inria.frCommMonitor::recvTimingSnoopReq(PacketPtr pkt) 38911784Sarthur.perais@inria.fr{ 39011784Sarthur.perais@inria.fr slavePort.sendTimingSnoopReq(pkt); 39111784Sarthur.perais@inria.fr} 39211784Sarthur.perais@inria.fr 39311784Sarthur.perais@inria.frbool 39411784Sarthur.perais@inria.frCommMonitor::recvTimingSnoopResp(PacketPtr pkt) 39511784Sarthur.perais@inria.fr{ 39611784Sarthur.perais@inria.fr return masterPort.sendTimingSnoopResp(pkt); 39711784Sarthur.perais@inria.fr} 39811784Sarthur.perais@inria.fr 39911784Sarthur.perais@inria.frbool 40011784Sarthur.perais@inria.frCommMonitor::isSnooping() const 40111784Sarthur.perais@inria.fr{ 40211784Sarthur.perais@inria.fr // check if the connected master port is snooping 40311784Sarthur.perais@inria.fr return slavePort.isSnooping(); 40411784Sarthur.perais@inria.fr} 40511784Sarthur.perais@inria.fr 40611784Sarthur.perais@inria.frAddrRangeList 40711784Sarthur.perais@inria.frCommMonitor::getAddrRanges() const 40811784Sarthur.perais@inria.fr{ 40911784Sarthur.perais@inria.fr // get the address ranges of the connected slave port 41011784Sarthur.perais@inria.fr return masterPort.getAddrRanges(); 41111784Sarthur.perais@inria.fr} 41211784Sarthur.perais@inria.fr 41311784Sarthur.perais@inria.frvoid 41411784Sarthur.perais@inria.frCommMonitor::recvRetryMaster() 41511784Sarthur.perais@inria.fr{ 41611784Sarthur.perais@inria.fr slavePort.sendRetry(); 41711784Sarthur.perais@inria.fr} 41811784Sarthur.perais@inria.fr 41911784Sarthur.perais@inria.frvoid 42011784Sarthur.perais@inria.frCommMonitor::recvRetrySlave() 42111784Sarthur.perais@inria.fr{ 42211784Sarthur.perais@inria.fr masterPort.sendRetry(); 42311784Sarthur.perais@inria.fr} 42411784Sarthur.perais@inria.fr 42511784Sarthur.perais@inria.frvoid 42611784Sarthur.perais@inria.frCommMonitor::recvRangeChange() 42711784Sarthur.perais@inria.fr{ 42811784Sarthur.perais@inria.fr slavePort.sendRangeChange(); 42911784Sarthur.perais@inria.fr} 43011784Sarthur.perais@inria.fr 43111784Sarthur.perais@inria.frvoid 43211784Sarthur.perais@inria.frCommMonitor::regStats() 43311784Sarthur.perais@inria.fr{ 43411784Sarthur.perais@inria.fr // Initialise all the monitor stats 43511784Sarthur.perais@inria.fr using namespace Stats; 43611784Sarthur.perais@inria.fr 43711784Sarthur.perais@inria.fr stats.readBurstLengthHist 43811784Sarthur.perais@inria.fr .init(params()->burst_length_bins) 43911784Sarthur.perais@inria.fr .name(name() + ".readBurstLengthHist") 44011784Sarthur.perais@inria.fr .desc("Histogram of burst lengths of transmitted packets") 44111784Sarthur.perais@inria.fr .flags(stats.disableBurstLengthHists ? nozero : pdf); 44211784Sarthur.perais@inria.fr 44311784Sarthur.perais@inria.fr stats.writeBurstLengthHist 44411784Sarthur.perais@inria.fr .init(params()->burst_length_bins) 44511784Sarthur.perais@inria.fr .name(name() + ".writeBurstLengthHist") 44611784Sarthur.perais@inria.fr .desc("Histogram of burst lengths of transmitted packets") 44711784Sarthur.perais@inria.fr .flags(stats.disableBurstLengthHists ? nozero : pdf); 44811784Sarthur.perais@inria.fr 44911784Sarthur.perais@inria.fr // Stats based on received responses 45011784Sarthur.perais@inria.fr stats.readBandwidthHist 45111784Sarthur.perais@inria.fr .init(params()->bandwidth_bins) 45211784Sarthur.perais@inria.fr .name(name() + ".readBandwidthHist") 45311784Sarthur.perais@inria.fr .desc("Histogram of read bandwidth per sample period (bytes/s)") 45411784Sarthur.perais@inria.fr .flags(stats.disableBandwidthHists ? nozero : pdf); 45511784Sarthur.perais@inria.fr 45611784Sarthur.perais@inria.fr stats.averageReadBW 45711784Sarthur.perais@inria.fr .name(name() + ".averageReadBandwidth") 45811784Sarthur.perais@inria.fr .desc("Average read bandwidth (bytes/s)") 45911784Sarthur.perais@inria.fr .flags(stats.disableBandwidthHists ? nozero : pdf); 46011784Sarthur.perais@inria.fr 46111784Sarthur.perais@inria.fr stats.totalReadBytes 46211784Sarthur.perais@inria.fr .name(name() + ".totalReadBytes") 46311784Sarthur.perais@inria.fr .desc("Number of bytes read") 46411784Sarthur.perais@inria.fr .flags(stats.disableBandwidthHists ? nozero : pdf); 46511784Sarthur.perais@inria.fr 46611784Sarthur.perais@inria.fr stats.averageReadBW = stats.totalReadBytes / simSeconds; 46711784Sarthur.perais@inria.fr 46811784Sarthur.perais@inria.fr // Stats based on successfully sent requests 46911784Sarthur.perais@inria.fr stats.writeBandwidthHist 47011784Sarthur.perais@inria.fr .init(params()->bandwidth_bins) 47111784Sarthur.perais@inria.fr .name(name() + ".writeBandwidthHist") 47211784Sarthur.perais@inria.fr .desc("Histogram of write bandwidth (bytes/s)") 47311784Sarthur.perais@inria.fr .flags(stats.disableBandwidthHists ? (pdf | nozero) : pdf); 47411784Sarthur.perais@inria.fr 47511784Sarthur.perais@inria.fr stats.averageWriteBW 47611784Sarthur.perais@inria.fr .name(name() + ".averageWriteBandwidth") 47711784Sarthur.perais@inria.fr .desc("Average write bandwidth (bytes/s)") 47811784Sarthur.perais@inria.fr .flags(stats.disableBandwidthHists ? nozero : pdf); 47911784Sarthur.perais@inria.fr 48011784Sarthur.perais@inria.fr stats.totalWrittenBytes 48111784Sarthur.perais@inria.fr .name(name() + ".totalWrittenBytes") 48211784Sarthur.perais@inria.fr .desc("Number of bytes written") 48311784Sarthur.perais@inria.fr .flags(stats.disableBandwidthHists ? nozero : pdf); 48411784Sarthur.perais@inria.fr 48511784Sarthur.perais@inria.fr stats.averageWriteBW = stats.totalWrittenBytes / simSeconds; 48611784Sarthur.perais@inria.fr 48711784Sarthur.perais@inria.fr stats.readLatencyHist 48811784Sarthur.perais@inria.fr .init(params()->latency_bins) 48911784Sarthur.perais@inria.fr .name(name() + ".readLatencyHist") 49011784Sarthur.perais@inria.fr .desc("Read request-response latency") 49111784Sarthur.perais@inria.fr .flags(stats.disableLatencyHists ? nozero : pdf); 49211784Sarthur.perais@inria.fr 49311784Sarthur.perais@inria.fr stats.writeLatencyHist 49411784Sarthur.perais@inria.fr .init(params()->latency_bins) 49511784Sarthur.perais@inria.fr .name(name() + ".writeLatencyHist") 49611784Sarthur.perais@inria.fr .desc("Write request-response latency") 49711784Sarthur.perais@inria.fr .flags(stats.disableLatencyHists ? nozero : pdf); 49811784Sarthur.perais@inria.fr 49911784Sarthur.perais@inria.fr stats.ittReadRead 50011784Sarthur.perais@inria.fr .init(1, params()->itt_max_bin, params()->itt_max_bin / 50111784Sarthur.perais@inria.fr params()->itt_bins) 50211784Sarthur.perais@inria.fr .name(name() + ".ittReadRead") 50311784Sarthur.perais@inria.fr .desc("Read-to-read inter transaction time") 50411784Sarthur.perais@inria.fr .flags(stats.disableITTDists ? nozero : pdf); 50511784Sarthur.perais@inria.fr 50611784Sarthur.perais@inria.fr stats.ittWriteWrite 50711784Sarthur.perais@inria.fr .init(1, params()->itt_max_bin, params()->itt_max_bin / 50811784Sarthur.perais@inria.fr params()->itt_bins) 50911784Sarthur.perais@inria.fr .name(name() + ".ittWriteWrite") 51011784Sarthur.perais@inria.fr .desc("Write-to-write inter transaction time") 51111784Sarthur.perais@inria.fr .flags(stats.disableITTDists ? nozero : pdf); 51211784Sarthur.perais@inria.fr 51311784Sarthur.perais@inria.fr stats.ittReqReq 51411784Sarthur.perais@inria.fr .init(1, params()->itt_max_bin, params()->itt_max_bin / 51511784Sarthur.perais@inria.fr params()->itt_bins) 51611784Sarthur.perais@inria.fr .name(name() + ".ittReqReq") 51711784Sarthur.perais@inria.fr .desc("Request-to-request inter transaction time") 51811784Sarthur.perais@inria.fr .flags(stats.disableITTDists ? nozero : pdf); 51911784Sarthur.perais@inria.fr 52011784Sarthur.perais@inria.fr stats.outstandingReadsHist 52111784Sarthur.perais@inria.fr .init(params()->outstanding_bins) 52211784Sarthur.perais@inria.fr .name(name() + ".outstandingReadsHist") 52311784Sarthur.perais@inria.fr .desc("Outstanding read transactions") 52411784Sarthur.perais@inria.fr .flags(stats.disableOutstandingHists ? nozero : pdf); 52511784Sarthur.perais@inria.fr 52611784Sarthur.perais@inria.fr stats.outstandingWritesHist 52711784Sarthur.perais@inria.fr .init(params()->outstanding_bins) 52811784Sarthur.perais@inria.fr .name(name() + ".outstandingWritesHist") 52911784Sarthur.perais@inria.fr .desc("Outstanding write transactions") 53011784Sarthur.perais@inria.fr .flags(stats.disableOutstandingHists ? nozero : pdf); 53111784Sarthur.perais@inria.fr 53211784Sarthur.perais@inria.fr stats.readTransHist 53311784Sarthur.perais@inria.fr .init(params()->transaction_bins) 53411784Sarthur.perais@inria.fr .name(name() + ".readTransHist") 53511784Sarthur.perais@inria.fr .desc("Histogram of read transactions per sample period") 53611784Sarthur.perais@inria.fr .flags(stats.disableTransactionHists ? nozero : pdf); 53711784Sarthur.perais@inria.fr 53811784Sarthur.perais@inria.fr stats.writeTransHist 53911784Sarthur.perais@inria.fr .init(params()->transaction_bins) 54011784Sarthur.perais@inria.fr .name(name() + ".writeTransHist") 54111784Sarthur.perais@inria.fr .desc("Histogram of read transactions per sample period") 54211784Sarthur.perais@inria.fr .flags(stats.disableTransactionHists ? nozero : pdf); 54311784Sarthur.perais@inria.fr 54411784Sarthur.perais@inria.fr stats.readAddrDist 54511784Sarthur.perais@inria.fr .init(0) 54611784Sarthur.perais@inria.fr .name(name() + ".readAddrDist") 54711784Sarthur.perais@inria.fr .desc("Read address distribution") 54811784Sarthur.perais@inria.fr .flags(stats.disableAddrDists ? nozero : pdf); 54911784Sarthur.perais@inria.fr 55011784Sarthur.perais@inria.fr stats.writeAddrDist 55111784Sarthur.perais@inria.fr .init(0) 55211784Sarthur.perais@inria.fr .name(name() + ".writeAddrDist") 55311784Sarthur.perais@inria.fr .desc("Write address distribution") 55411784Sarthur.perais@inria.fr .flags(stats.disableAddrDists ? nozero : pdf); 55511784Sarthur.perais@inria.fr} 55611784Sarthur.perais@inria.fr 55711784Sarthur.perais@inria.frvoid 55811784Sarthur.perais@inria.frCommMonitor::samplePeriodic() 55911784Sarthur.perais@inria.fr{ 56011784Sarthur.perais@inria.fr // the periodic stats update runs on the granularity of sample 56111784Sarthur.perais@inria.fr // periods, but in combination with this there may also be a 56211784Sarthur.perais@inria.fr // external resets and dumps of the stats (through schedStatEvent) 56311784Sarthur.perais@inria.fr // causing the stats themselves to capture less than a sample 56411784Sarthur.perais@inria.fr // period 56511784Sarthur.perais@inria.fr 56611784Sarthur.perais@inria.fr // only capture if we have not reset the stats during the last 56711784Sarthur.perais@inria.fr // sample period 56811784Sarthur.perais@inria.fr if (simTicks.value() >= samplePeriodTicks) { 56911784Sarthur.perais@inria.fr if (!stats.disableTransactionHists) { 57011784Sarthur.perais@inria.fr stats.readTransHist.sample(stats.readTrans); 57111784Sarthur.perais@inria.fr stats.writeTransHist.sample(stats.writeTrans); 57211784Sarthur.perais@inria.fr } 57311784Sarthur.perais@inria.fr 57411784Sarthur.perais@inria.fr if (!stats.disableBandwidthHists) { 57511784Sarthur.perais@inria.fr stats.readBandwidthHist.sample(stats.readBytes / samplePeriod); 57611784Sarthur.perais@inria.fr stats.writeBandwidthHist.sample(stats.writtenBytes / samplePeriod); 57711784Sarthur.perais@inria.fr } 57811784Sarthur.perais@inria.fr 57911784Sarthur.perais@inria.fr if (!stats.disableOutstandingHists) { 58011784Sarthur.perais@inria.fr stats.outstandingReadsHist.sample(stats.outstandingReadReqs); 58111784Sarthur.perais@inria.fr stats.outstandingWritesHist.sample(stats.outstandingWriteReqs); 58211784Sarthur.perais@inria.fr } 58311784Sarthur.perais@inria.fr } 58411784Sarthur.perais@inria.fr 58511784Sarthur.perais@inria.fr // reset the sampled values 58611784Sarthur.perais@inria.fr stats.readTrans = 0; 58711784Sarthur.perais@inria.fr stats.writeTrans = 0; 58811784Sarthur.perais@inria.fr 58911784Sarthur.perais@inria.fr stats.readBytes = 0; 59011784Sarthur.perais@inria.fr stats.writtenBytes = 0; 59111784Sarthur.perais@inria.fr 59211784Sarthur.perais@inria.fr schedule(samplePeriodicEvent, curTick() + samplePeriodTicks); 59311784Sarthur.perais@inria.fr} 59411784Sarthur.perais@inria.fr 59511784Sarthur.perais@inria.frvoid 59611784Sarthur.perais@inria.frCommMonitor::startup() 59711784Sarthur.perais@inria.fr{ 59811784Sarthur.perais@inria.fr schedule(samplePeriodicEvent, curTick() + samplePeriodTicks); 59911784Sarthur.perais@inria.fr} 60011784Sarthur.perais@inria.fr