comm_monitor.cc revision 8981
15081Sgblack@eecs.umich.edu/* 25081Sgblack@eecs.umich.edu * Copyright (c) 2012 ARM Limited 35081Sgblack@eecs.umich.edu * All rights reserved 47087Snate@binkert.org * 57087Snate@binkert.org * The license below extends only to copyright in the software and shall 67087Snate@binkert.org * not be construed as granting a license to any other intellectual 77087Snate@binkert.org * property including but not limited to intellectual property relating 87087Snate@binkert.org * to a hardware implementation of the functionality of the software 97087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 125081Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137087Snate@binkert.org * 147087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 157087Snate@binkert.org * modification, are permitted provided that the following conditions are 167087Snate@binkert.org * met: redistributions of source code must retain the above copyright 177087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 187087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 197087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 207087Snate@binkert.org * documentation and/or other materials provided with the distribution; 215081Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 227087Snate@binkert.org * contributors may be used to endorse or promote products derived from 235081Sgblack@eecs.umich.edu * this software without specific prior written permission. 245081Sgblack@eecs.umich.edu * 255081Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 265081Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 275081Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 285081Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 295081Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 305081Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 315081Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 325081Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 335081Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 345081Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 355081Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 365081Sgblack@eecs.umich.edu * 375081Sgblack@eecs.umich.edu * Authors: Thomas Grass 385081Sgblack@eecs.umich.edu * Andreas Hansson 395081Sgblack@eecs.umich.edu */ 405081Sgblack@eecs.umich.edu 415961Sgblack@eecs.umich.edu#include "debug/CommMonitor.hh" 425081Sgblack@eecs.umich.edu#include "mem/comm_monitor.hh" 435081Sgblack@eecs.umich.edu#include "sim/stats.hh" 445081Sgblack@eecs.umich.edu 455081Sgblack@eecs.umich.eduCommMonitor::CommMonitor(Params* params) 465119Sgblack@eecs.umich.edu : MemObject(params), 475961Sgblack@eecs.umich.edu masterPort(name() + "-master", *this), 485081Sgblack@eecs.umich.edu slavePort(name() + "-slave", *this), 495081Sgblack@eecs.umich.edu samplePeriodicEvent(this), 505081Sgblack@eecs.umich.edu samplePeriodTicks(params->sample_period), 515081Sgblack@eecs.umich.edu readAddrMask(params->read_addr_mask), 525081Sgblack@eecs.umich.edu writeAddrMask(params->write_addr_mask), 535081Sgblack@eecs.umich.edu stats(params) 545119Sgblack@eecs.umich.edu{ 555961Sgblack@eecs.umich.edu // keep track of the sample period both in ticks and absolute time 565081Sgblack@eecs.umich.edu samplePeriod.setTick(params->sample_period); 575081Sgblack@eecs.umich.edu 585081Sgblack@eecs.umich.edu DPRINTF(CommMonitor, 595081Sgblack@eecs.umich.edu "Created monitor %s with sample period %d ticks (%f s)\n", 605081Sgblack@eecs.umich.edu name(), samplePeriodTicks, samplePeriod); 615961Sgblack@eecs.umich.edu} 625081Sgblack@eecs.umich.edu 635081Sgblack@eecs.umich.eduCommMonitor* 645081Sgblack@eecs.umich.eduCommMonitorParams::create() 655081Sgblack@eecs.umich.edu{ 665119Sgblack@eecs.umich.edu return new CommMonitor(this); 675961Sgblack@eecs.umich.edu} 685081Sgblack@eecs.umich.edu 695081Sgblack@eecs.umich.eduvoid 705081Sgblack@eecs.umich.eduCommMonitor::init() 715081Sgblack@eecs.umich.edu{ 725081Sgblack@eecs.umich.edu // make sure both sides of the monitor are connected 735081Sgblack@eecs.umich.edu if (!slavePort.isConnected() || !masterPort.isConnected()) 745119Sgblack@eecs.umich.edu fatal("Communication monitor is not connected on both sides.\n"); 755961Sgblack@eecs.umich.edu} 765081Sgblack@eecs.umich.edu 775081Sgblack@eecs.umich.eduMasterPort& 785081Sgblack@eecs.umich.eduCommMonitor::getMasterPort(const std::string& if_name, int idx) 795081Sgblack@eecs.umich.edu{ 805081Sgblack@eecs.umich.edu if (if_name == "master") { 815961Sgblack@eecs.umich.edu return masterPort; 825081Sgblack@eecs.umich.edu } else { 835081Sgblack@eecs.umich.edu return MemObject::getMasterPort(if_name, idx); 845081Sgblack@eecs.umich.edu } 855081Sgblack@eecs.umich.edu} 865119Sgblack@eecs.umich.edu 875961Sgblack@eecs.umich.eduSlavePort& 885081Sgblack@eecs.umich.eduCommMonitor::getSlavePort(const std::string& if_name, int idx) 895081Sgblack@eecs.umich.edu{ 905081Sgblack@eecs.umich.edu if (if_name == "slave") { 915081Sgblack@eecs.umich.edu return slavePort; 925081Sgblack@eecs.umich.edu } else { 935081Sgblack@eecs.umich.edu return MemObject::getSlavePort(if_name, idx); 945119Sgblack@eecs.umich.edu } 955961Sgblack@eecs.umich.edu} 965081Sgblack@eecs.umich.edu 975081Sgblack@eecs.umich.eduvoid 985081Sgblack@eecs.umich.eduCommMonitor::recvFunctional(PacketPtr pkt) 996480Sgblack@eecs.umich.edu{ 1006480Sgblack@eecs.umich.edu masterPort.sendFunctional(pkt); 1016480Sgblack@eecs.umich.edu} 1026480Sgblack@eecs.umich.edu 1036480Sgblack@eecs.umich.eduvoid 1046480Sgblack@eecs.umich.eduCommMonitor::recvFunctionalSnoop(PacketPtr pkt) 1056480Sgblack@eecs.umich.edu{ 1066480Sgblack@eecs.umich.edu slavePort.sendFunctionalSnoop(pkt); 1076480Sgblack@eecs.umich.edu} 1086480Sgblack@eecs.umich.edu 1096480Sgblack@eecs.umich.eduTick 1106480Sgblack@eecs.umich.eduCommMonitor::recvAtomic(PacketPtr pkt) 1116480Sgblack@eecs.umich.edu{ 1126480Sgblack@eecs.umich.edu return masterPort.sendAtomic(pkt); 1136480Sgblack@eecs.umich.edu} 1146480Sgblack@eecs.umich.edu 1156480Sgblack@eecs.umich.eduTick 1166480Sgblack@eecs.umich.eduCommMonitor::recvAtomicSnoop(PacketPtr pkt) 1176480Sgblack@eecs.umich.edu{ 1186480Sgblack@eecs.umich.edu return slavePort.sendAtomicSnoop(pkt); 1196480Sgblack@eecs.umich.edu} 1206480Sgblack@eecs.umich.edu 1216480Sgblack@eecs.umich.edubool 1226480Sgblack@eecs.umich.eduCommMonitor::recvTimingReq(PacketPtr pkt) 1236480Sgblack@eecs.umich.edu{ 1246480Sgblack@eecs.umich.edu // should always see a request 1256480Sgblack@eecs.umich.edu assert(pkt->isRequest()); 1266480Sgblack@eecs.umich.edu 1276480Sgblack@eecs.umich.edu // Store relevant fields of packet, because packet may be modified 1286480Sgblack@eecs.umich.edu // or even deleted when sendTiming() is called. 1296480Sgblack@eecs.umich.edu bool isRead = pkt->isRead(); 1306480Sgblack@eecs.umich.edu bool isWrite = pkt->isWrite(); 1316480Sgblack@eecs.umich.edu unsigned size = pkt->getSize(); 1326480Sgblack@eecs.umich.edu Addr addr = pkt->getAddr(); 1336480Sgblack@eecs.umich.edu bool needsResponse = pkt->needsResponse(); 1346480Sgblack@eecs.umich.edu bool memInhibitAsserted = pkt->memInhibitAsserted(); 1356480Sgblack@eecs.umich.edu Packet::SenderState* senderState = pkt->senderState; 1366480Sgblack@eecs.umich.edu 1376480Sgblack@eecs.umich.edu // If a cache miss is served by a cache, a monitor near the memory 1386480Sgblack@eecs.umich.edu // would see a request which needs a response, but this response 1396480Sgblack@eecs.umich.edu // would be inhibited and not come back from the memory. Therefore 1406480Sgblack@eecs.umich.edu // we additionally have to check the inhibit flag. 1416480Sgblack@eecs.umich.edu if (needsResponse && !memInhibitAsserted && !stats.disableLatencyHists) { 1426480Sgblack@eecs.umich.edu pkt->senderState = new CommMonitorSenderState(senderState, 1436480Sgblack@eecs.umich.edu curTick()); 1446480Sgblack@eecs.umich.edu } 1455081Sgblack@eecs.umich.edu 1465081Sgblack@eecs.umich.edu // Attempt to send the packet (always succeeds for inhibited 1475961Sgblack@eecs.umich.edu // packets) 1485081Sgblack@eecs.umich.edu bool successful = masterPort.sendTimingReq(pkt); 1495081Sgblack@eecs.umich.edu 1505081Sgblack@eecs.umich.edu // If not successful, restore the sender state 1515081Sgblack@eecs.umich.edu if (!successful && needsResponse && !stats.disableLatencyHists) { 1525119Sgblack@eecs.umich.edu delete pkt->senderState; 1535961Sgblack@eecs.umich.edu pkt->senderState = senderState; 1545081Sgblack@eecs.umich.edu } 1555081Sgblack@eecs.umich.edu 1565081Sgblack@eecs.umich.edu if (successful && isRead) { 1575081Sgblack@eecs.umich.edu DPRINTF(CommMonitor, "Forwarded read request\n"); 1585081Sgblack@eecs.umich.edu 1595081Sgblack@eecs.umich.edu // Increment number of observed read transactions 1605119Sgblack@eecs.umich.edu if (!stats.disableTransactionHists) { 1615961Sgblack@eecs.umich.edu ++stats.readTrans; 1625081Sgblack@eecs.umich.edu } 1635081Sgblack@eecs.umich.edu 1645081Sgblack@eecs.umich.edu // Get sample of burst length 1655081Sgblack@eecs.umich.edu if (!stats.disableBurstLengthHists) { 1665081Sgblack@eecs.umich.edu stats.readBurstLengthHist.sample(size); 1675961Sgblack@eecs.umich.edu } 1685081Sgblack@eecs.umich.edu 1695081Sgblack@eecs.umich.edu // Sample the masked address 1705081Sgblack@eecs.umich.edu if (!stats.disableAddrDists) { 1715081Sgblack@eecs.umich.edu stats.readAddrDist.sample(addr & readAddrMask); 1725119Sgblack@eecs.umich.edu } 1735961Sgblack@eecs.umich.edu 1745081Sgblack@eecs.umich.edu // If it needs a response increment number of outstanding read 1755081Sgblack@eecs.umich.edu // requests 1765081Sgblack@eecs.umich.edu if (!stats.disableOutstandingHists && needsResponse) { 1775081Sgblack@eecs.umich.edu ++stats.outstandingReadReqs; 1785081Sgblack@eecs.umich.edu } 1795081Sgblack@eecs.umich.edu 1805119Sgblack@eecs.umich.edu if (!stats.disableITTDists) { 1815961Sgblack@eecs.umich.edu // Sample value of read-read inter transaction time 1825081Sgblack@eecs.umich.edu if (stats.timeOfLastRead != 0) { 1835081Sgblack@eecs.umich.edu stats.ittReadRead.sample(curTick() - stats.timeOfLastRead); 1845081Sgblack@eecs.umich.edu } 1855081Sgblack@eecs.umich.edu stats.timeOfLastRead = curTick(); 1865081Sgblack@eecs.umich.edu 1875961Sgblack@eecs.umich.edu // Sample value of req-req inter transaction time 1885081Sgblack@eecs.umich.edu if (stats.timeOfLastReq != 0) { 1895081Sgblack@eecs.umich.edu stats.ittReqReq.sample(curTick() - stats.timeOfLastReq); 1905081Sgblack@eecs.umich.edu } 1915081Sgblack@eecs.umich.edu stats.timeOfLastReq = curTick(); 1925119Sgblack@eecs.umich.edu } 1935961Sgblack@eecs.umich.edu } else if (successful && isWrite) { 1945081Sgblack@eecs.umich.edu DPRINTF(CommMonitor, "Forwarded write request\n"); 1955081Sgblack@eecs.umich.edu 1965081Sgblack@eecs.umich.edu // Same as for reads 1975081Sgblack@eecs.umich.edu if (!stats.disableTransactionHists) { 1985081Sgblack@eecs.umich.edu ++stats.writeTrans; 1995081Sgblack@eecs.umich.edu } 2005119Sgblack@eecs.umich.edu 2015961Sgblack@eecs.umich.edu if (!stats.disableBurstLengthHists) { 2025081Sgblack@eecs.umich.edu stats.writeBurstLengthHist.sample(size); 2035081Sgblack@eecs.umich.edu } 2045081Sgblack@eecs.umich.edu 2056481Sgblack@eecs.umich.edu // Update the bandwidth stats on the request 2066481Sgblack@eecs.umich.edu if (!stats.disableBandwidthHists) { 2076481Sgblack@eecs.umich.edu stats.writtenBytes += size; 2086481Sgblack@eecs.umich.edu stats.totalWrittenBytes += size; 2096481Sgblack@eecs.umich.edu } 2106481Sgblack@eecs.umich.edu 2116481Sgblack@eecs.umich.edu // Sample the masked write address 2126481Sgblack@eecs.umich.edu if (!stats.disableAddrDists) { 2136481Sgblack@eecs.umich.edu stats.writeAddrDist.sample(addr & writeAddrMask); 2146481Sgblack@eecs.umich.edu } 2156481Sgblack@eecs.umich.edu 2166481Sgblack@eecs.umich.edu if (!stats.disableOutstandingHists && needsResponse) { 2176481Sgblack@eecs.umich.edu ++stats.outstandingWriteReqs; 2186481Sgblack@eecs.umich.edu } 2196481Sgblack@eecs.umich.edu 2206481Sgblack@eecs.umich.edu if (!stats.disableITTDists) { 2216481Sgblack@eecs.umich.edu // Sample value of write-to-write inter transaction time 2226481Sgblack@eecs.umich.edu if (stats.timeOfLastWrite != 0) { 2236481Sgblack@eecs.umich.edu stats.ittWriteWrite.sample(curTick() - stats.timeOfLastWrite); 2246481Sgblack@eecs.umich.edu } 2256481Sgblack@eecs.umich.edu stats.timeOfLastWrite = curTick(); 2266481Sgblack@eecs.umich.edu 2276481Sgblack@eecs.umich.edu // Sample value of req-to-req inter transaction time 2285977Sgblack@eecs.umich.edu if (stats.timeOfLastReq != 0) { 2295977Sgblack@eecs.umich.edu stats.ittReqReq.sample(curTick() - stats.timeOfLastReq); 2306481Sgblack@eecs.umich.edu } 2316481Sgblack@eecs.umich.edu stats.timeOfLastReq = curTick(); 2325977Sgblack@eecs.umich.edu } 2335977Sgblack@eecs.umich.edu } else if (successful) { 2345977Sgblack@eecs.umich.edu DPRINTF(CommMonitor, "Forwarded non read/write request\n"); 2355977Sgblack@eecs.umich.edu } 2365977Sgblack@eecs.umich.edu 2376481Sgblack@eecs.umich.edu return successful; 2386481Sgblack@eecs.umich.edu} 2395977Sgblack@eecs.umich.edu 2405977Sgblack@eecs.umich.edubool 2415977Sgblack@eecs.umich.eduCommMonitor::recvTimingResp(PacketPtr pkt) 2425977Sgblack@eecs.umich.edu{ 2435977Sgblack@eecs.umich.edu // should always see responses 2445977Sgblack@eecs.umich.edu assert(pkt->isResponse()); 2455977Sgblack@eecs.umich.edu 2466481Sgblack@eecs.umich.edu // Store relevant fields of packet, because packet may be modified 2476481Sgblack@eecs.umich.edu // or even deleted when sendTiming() is called. 2485977Sgblack@eecs.umich.edu bool isRead = pkt->isRead(); 2495977Sgblack@eecs.umich.edu bool isWrite = pkt->isWrite(); 2505977Sgblack@eecs.umich.edu unsigned size = pkt->getSize(); 2515081Sgblack@eecs.umich.edu Tick latency = 0; 2525081Sgblack@eecs.umich.edu CommMonitorSenderState* commReceivedState = 2535961Sgblack@eecs.umich.edu dynamic_cast<CommMonitorSenderState*>(pkt->senderState); 2545081Sgblack@eecs.umich.edu 2555081Sgblack@eecs.umich.edu if (!stats.disableLatencyHists) { 2565081Sgblack@eecs.umich.edu // Restore initial sender state 2575081Sgblack@eecs.umich.edu if (commReceivedState == NULL) 2585119Sgblack@eecs.umich.edu panic("Monitor got a response without monitor sender state\n"); 2595961Sgblack@eecs.umich.edu 2605081Sgblack@eecs.umich.edu // Restore the sate 2615081Sgblack@eecs.umich.edu pkt->senderState = commReceivedState->origSenderState; 2625081Sgblack@eecs.umich.edu } 2635081Sgblack@eecs.umich.edu 2645081Sgblack@eecs.umich.edu // Attempt to send the packet 2655081Sgblack@eecs.umich.edu bool successful = slavePort.sendTimingResp(pkt); 2665119Sgblack@eecs.umich.edu 2675961Sgblack@eecs.umich.edu if (!stats.disableLatencyHists) { 2685081Sgblack@eecs.umich.edu // If packet successfully send, sample value of latency, 2695081Sgblack@eecs.umich.edu // afterwards delete sender state, otherwise restore state 2705081Sgblack@eecs.umich.edu if (successful) { 2715081Sgblack@eecs.umich.edu latency = curTick() - commReceivedState->transmitTime; 2725081Sgblack@eecs.umich.edu DPRINTF(CommMonitor, "Latency: %d\n", latency); 2735961Sgblack@eecs.umich.edu delete commReceivedState; 2745081Sgblack@eecs.umich.edu } else { 2755081Sgblack@eecs.umich.edu // Don't delete anything and let the packet look like we 2765081Sgblack@eecs.umich.edu // did not touch it 2775081Sgblack@eecs.umich.edu pkt->senderState = commReceivedState; 2785119Sgblack@eecs.umich.edu } 2795961Sgblack@eecs.umich.edu } 2805081Sgblack@eecs.umich.edu 2815081Sgblack@eecs.umich.edu if (successful && isRead) { 2825081Sgblack@eecs.umich.edu // Decrement number of outstanding read requests 2835081Sgblack@eecs.umich.edu DPRINTF(CommMonitor, "Received read response\n"); 2845081Sgblack@eecs.umich.edu if (!stats.disableOutstandingHists) { 2855081Sgblack@eecs.umich.edu assert(stats.outstandingReadReqs != 0); 2865119Sgblack@eecs.umich.edu --stats.outstandingReadReqs; 2875961Sgblack@eecs.umich.edu } 2885081Sgblack@eecs.umich.edu 2895081Sgblack@eecs.umich.edu if (!stats.disableLatencyHists) { 2905081Sgblack@eecs.umich.edu stats.readLatencyHist.sample(latency); 2915081Sgblack@eecs.umich.edu } 2925081Sgblack@eecs.umich.edu 2935961Sgblack@eecs.umich.edu // Update the bandwidth stats based on responses for reads 2945081Sgblack@eecs.umich.edu if (!stats.disableBandwidthHists) { 2955081Sgblack@eecs.umich.edu stats.readBytes += size; 2965081Sgblack@eecs.umich.edu stats.totalReadBytes += size; 2975081Sgblack@eecs.umich.edu } 2985119Sgblack@eecs.umich.edu 2995961Sgblack@eecs.umich.edu } else if (successful && isWrite) { 3005081Sgblack@eecs.umich.edu // Decrement number of outstanding write requests 3015081Sgblack@eecs.umich.edu DPRINTF(CommMonitor, "Received write response\n"); 3025081Sgblack@eecs.umich.edu if (!stats.disableOutstandingHists) { 3035081Sgblack@eecs.umich.edu assert(stats.outstandingWriteReqs != 0); 3045081Sgblack@eecs.umich.edu --stats.outstandingWriteReqs; 3055081Sgblack@eecs.umich.edu } 3065119Sgblack@eecs.umich.edu 3075961Sgblack@eecs.umich.edu if (!stats.disableLatencyHists) { 3085081Sgblack@eecs.umich.edu stats.writeLatencyHist.sample(latency); 3095081Sgblack@eecs.umich.edu } 3105081Sgblack@eecs.umich.edu } else if (successful) { 311 DPRINTF(CommMonitor, "Received non read/write response\n"); 312 } 313 return successful; 314} 315 316void 317CommMonitor::recvTimingSnoopReq(PacketPtr pkt) 318{ 319 slavePort.sendTimingSnoopReq(pkt); 320} 321 322bool 323CommMonitor::recvTimingSnoopResp(PacketPtr pkt) 324{ 325 return masterPort.sendTimingSnoopResp(pkt); 326} 327 328bool 329CommMonitor::isSnooping() const 330{ 331 return slavePort.getMasterPort().isSnooping(); 332} 333 334unsigned 335CommMonitor::deviceBlockSizeMaster() 336{ 337 return slavePort.peerBlockSize(); 338} 339 340unsigned 341CommMonitor::deviceBlockSizeSlave() 342{ 343 return masterPort.peerBlockSize(); 344} 345 346AddrRangeList 347CommMonitor::getAddrRanges() 348{ 349 return masterPort.getSlavePort().getAddrRanges(); 350} 351 352void 353CommMonitor::recvRetryMaster() 354{ 355 slavePort.sendRetry(); 356} 357 358void 359CommMonitor::recvRetrySlave() 360{ 361 masterPort.sendRetry(); 362} 363 364void 365CommMonitor::recvRangeChange() 366{ 367 slavePort.sendRangeChange(); 368} 369 370void 371CommMonitor::regStats() 372{ 373 // Initialise all the monitor stats 374 using namespace Stats; 375 376 stats.readBurstLengthHist 377 .init(params()->burst_length_bins) 378 .name(name() + ".readBurstLengthHist") 379 .desc("Histogram of burst lengths of transmitted packets") 380 .flags(stats.disableBurstLengthHists ? nozero : pdf); 381 382 stats.writeBurstLengthHist 383 .init(params()->burst_length_bins) 384 .name(name() + ".writeBurstLengthHist") 385 .desc("Histogram of burst lengths of transmitted packets") 386 .flags(stats.disableBurstLengthHists ? nozero : pdf); 387 388 // Stats based on received responses 389 stats.readBandwidthHist 390 .init(params()->bandwidth_bins) 391 .name(name() + ".readBandwidthHist") 392 .desc("Histogram of read bandwidth per sample period (bytes/s)") 393 .flags(stats.disableBandwidthHists ? nozero : pdf); 394 395 stats.averageReadBW 396 .name(name() + ".averageReadBandwidth") 397 .desc("Average read bandwidth (bytes/s)") 398 .flags(stats.disableBandwidthHists ? nozero : pdf); 399 400 stats.totalReadBytes 401 .name(name() + ".totalReadBytes") 402 .desc("Number of bytes read") 403 .flags(stats.disableBandwidthHists ? nozero : pdf); 404 405 stats.averageReadBW = stats.totalReadBytes / simSeconds; 406 407 // Stats based on successfully sent requests 408 stats.writeBandwidthHist 409 .init(params()->bandwidth_bins) 410 .name(name() + ".writeBandwidthHist") 411 .desc("Histogram of write bandwidth (bytes/s)") 412 .flags(stats.disableBandwidthHists ? (pdf | nozero) : pdf); 413 414 stats.averageWriteBW 415 .name(name() + ".averageWriteBandwidth") 416 .desc("Average write bandwidth (bytes/s)") 417 .flags(stats.disableBandwidthHists ? nozero : pdf); 418 419 stats.totalWrittenBytes 420 .name(name() + ".totalWrittenBytes") 421 .desc("Number of bytes written") 422 .flags(stats.disableBandwidthHists ? nozero : pdf); 423 424 stats.averageWriteBW = stats.totalWrittenBytes / simSeconds; 425 426 stats.readLatencyHist 427 .init(params()->latency_bins) 428 .name(name() + ".readLatencyHist") 429 .desc("Read request-response latency") 430 .flags(stats.disableLatencyHists ? nozero : pdf); 431 432 stats.writeLatencyHist 433 .init(params()->latency_bins) 434 .name(name() + ".writeLatencyHist") 435 .desc("Write request-response latency") 436 .flags(stats.disableLatencyHists ? nozero : pdf); 437 438 stats.ittReadRead 439 .init(1, params()->itt_max_bin, params()->itt_max_bin / 440 params()->itt_bins) 441 .name(name() + ".ittReadRead") 442 .desc("Read-to-read inter transaction time") 443 .flags(stats.disableITTDists ? nozero : pdf); 444 445 stats.ittWriteWrite 446 .init(1, params()->itt_max_bin, params()->itt_max_bin / 447 params()->itt_bins) 448 .name(name() + ".ittWriteWrite") 449 .desc("Write-to-write inter transaction time") 450 .flags(stats.disableITTDists ? nozero : pdf); 451 452 stats.ittReqReq 453 .init(1, params()->itt_max_bin, params()->itt_max_bin / 454 params()->itt_bins) 455 .name(name() + ".ittReqReq") 456 .desc("Request-to-request inter transaction time") 457 .flags(stats.disableITTDists ? nozero : pdf); 458 459 stats.outstandingReadsHist 460 .init(params()->outstanding_bins) 461 .name(name() + ".outstandingReadsHist") 462 .desc("Outstanding read transactions") 463 .flags(stats.disableOutstandingHists ? nozero : pdf); 464 465 stats.outstandingWritesHist 466 .init(params()->outstanding_bins) 467 .name(name() + ".outstandingWritesHist") 468 .desc("Outstanding write transactions") 469 .flags(stats.disableOutstandingHists ? nozero : pdf); 470 471 stats.readTransHist 472 .init(params()->transaction_bins) 473 .name(name() + ".readTransHist") 474 .desc("Histogram of read transactions per sample period") 475 .flags(stats.disableTransactionHists ? nozero : pdf); 476 477 stats.writeTransHist 478 .init(params()->transaction_bins) 479 .name(name() + ".writeTransHist") 480 .desc("Histogram of read transactions per sample period") 481 .flags(stats.disableTransactionHists ? nozero : pdf); 482 483 stats.readAddrDist 484 .init(0) 485 .name(name() + ".readAddrDist") 486 .desc("Read address distribution") 487 .flags(stats.disableAddrDists ? nozero : pdf); 488 489 stats.writeAddrDist 490 .init(0) 491 .name(name() + ".writeAddrDist") 492 .desc("Write address distribution") 493 .flags(stats.disableAddrDists ? nozero : pdf); 494} 495 496void 497CommMonitor::samplePeriodic() 498{ 499 // the periodic stats update runs on the granularity of sample 500 // periods, but in combination with this there may also be a 501 // external resets and dumps of the stats (through schedStatEvent) 502 // causing the stats themselves to capture less than a sample 503 // period 504 505 // only capture if we have not reset the stats during the last 506 // sample period 507 if (simTicks.value() >= samplePeriodTicks) { 508 if (!stats.disableTransactionHists) { 509 stats.readTransHist.sample(stats.readTrans); 510 stats.writeTransHist.sample(stats.writeTrans); 511 } 512 513 if (!stats.disableBandwidthHists) { 514 stats.readBandwidthHist.sample(stats.readBytes / samplePeriod); 515 stats.writeBandwidthHist.sample(stats.writtenBytes / samplePeriod); 516 } 517 518 if (!stats.disableOutstandingHists) { 519 stats.outstandingReadsHist.sample(stats.outstandingReadReqs); 520 stats.outstandingWritesHist.sample(stats.outstandingWriteReqs); 521 } 522 } 523 524 // reset the sampled values 525 stats.readTrans = 0; 526 stats.writeTrans = 0; 527 528 stats.readBytes = 0; 529 stats.writtenBytes = 0; 530 531 schedule(samplePeriodicEvent, curTick() + samplePeriodTicks); 532} 533 534void 535CommMonitor::startup() 536{ 537 schedule(samplePeriodicEvent, curTick() + samplePeriodTicks); 538} 539