comm_monitor.hh revision 8981:6f4ec692716f
1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Thomas Grass 38 * Andreas Hansson 39 */ 40 41#ifndef __MEM_COMM_MONITOR_HH__ 42#define __MEM_COMM_MONITOR_HH__ 43 44#include "base/statistics.hh" 45#include "base/time.hh" 46#include "mem/mem_object.hh" 47#include "params/CommMonitor.hh" 48 49/** 50 * The communication monitor is a MemObject which can monitor statistics of 51 * the communication happening between two ports in the memory system. 52 * 53 * Currently the following stats are implemented: Histograms of read/write 54 * transactions, read/write burst lengths, read/write bandwidth, 55 * outstanding read/write requests, read latency and inter transaction time 56 * (read-read, write-write, read/write-read/write). Furthermore it allows 57 * to capture the number of accesses to an address over time ("heat map"). 58 * All stats can be disabled from Python. 59 */ 60class CommMonitor : public MemObject 61{ 62 63 public: 64 65 /** Parameters of communication monitor */ 66 typedef CommMonitorParams Params; 67 const Params* params() const 68 { return reinterpret_cast<const Params*>(_params); } 69 70 /** 71 * Constructor based on the Python params 72 * 73 * @param params Python parameters 74 */ 75 CommMonitor(Params* params); 76 77 /** Destructor */ 78 ~CommMonitor() { } 79 80 virtual MasterPort& getMasterPort(const std::string& if_name, 81 int idx = -1); 82 83 virtual SlavePort& getSlavePort(const std::string& if_name, 84 int idx = -1); 85 86 virtual void init(); 87 88 /** Register statistics */ 89 void regStats(); 90 91 private: 92 93 /** 94 * Sender state class for the monitor so that we can annotate 95 * packets with a transmit time and receive time. 96 */ 97 class CommMonitorSenderState : public Packet::SenderState 98 { 99 100 public: 101 102 /** 103 * Construct a new sender state and remember the original one 104 * so that we can implement a stack. 105 * 106 * @param _origSenderState Sender state to remember 107 * @param _transmitTime Time of packet transmission 108 */ 109 CommMonitorSenderState(SenderState* _origSenderState, 110 Tick _transmitTime) 111 : origSenderState(_origSenderState), transmitTime(_transmitTime) 112 { } 113 114 /** Destructor */ 115 ~CommMonitorSenderState() { } 116 117 /** Pointer to old sender state of packet */ 118 SenderState* origSenderState; 119 120 /** Tick when request is transmitted */ 121 Tick transmitTime; 122 123 }; 124 125 /** 126 * This is the master port of the communication monitor. All recv 127 * functions call a function in CommMonitor, where the 128 * send function of the slave port is called. Besides this, these 129 * functions can also perform actions for capturing statistics. 130 */ 131 class MonitorMasterPort : public MasterPort 132 { 133 134 public: 135 136 MonitorMasterPort(const std::string& _name, CommMonitor& _mon) 137 : MasterPort(_name, &_mon), mon(_mon) 138 { } 139 140 protected: 141 142 void recvFunctionalSnoop(PacketPtr pkt) 143 { 144 mon.recvFunctionalSnoop(pkt); 145 } 146 147 Tick recvAtomicSnoop(PacketPtr pkt) 148 { 149 return mon.recvAtomicSnoop(pkt); 150 } 151 152 bool recvTimingResp(PacketPtr pkt) 153 { 154 return mon.recvTimingResp(pkt); 155 } 156 157 void recvTimingSnoopReq(PacketPtr pkt) 158 { 159 mon.recvTimingSnoopReq(pkt); 160 } 161 162 void recvRangeChange() 163 { 164 mon.recvRangeChange(); 165 } 166 167 bool isSnooping() const 168 { 169 return mon.isSnooping(); 170 } 171 172 unsigned deviceBlockSize() const 173 { 174 return mon.deviceBlockSizeMaster(); 175 } 176 177 void recvRetry() 178 { 179 mon.recvRetryMaster(); 180 } 181 182 private: 183 184 CommMonitor& mon; 185 186 }; 187 188 /** Instance of master port, facing the memory side */ 189 MonitorMasterPort masterPort; 190 191 /** 192 * This is the slave port of the communication monitor. All recv 193 * functions call a function in CommMonitor, where the 194 * send function of the master port is called. Besides this, these 195 * functions can also perform actions for capturing statistics. 196 */ 197 class MonitorSlavePort : public SlavePort 198 { 199 200 public: 201 202 MonitorSlavePort(const std::string& _name, CommMonitor& _mon) 203 : SlavePort(_name, &_mon), mon(_mon) 204 { } 205 206 protected: 207 208 void recvFunctional(PacketPtr pkt) 209 { 210 mon.recvFunctional(pkt); 211 } 212 213 Tick recvAtomic(PacketPtr pkt) 214 { 215 return mon.recvAtomic(pkt); 216 } 217 218 bool recvTimingReq(PacketPtr pkt) 219 { 220 return mon.recvTimingReq(pkt); 221 } 222 223 bool recvTimingSnoopResp(PacketPtr pkt) 224 { 225 return mon.recvTimingSnoopResp(pkt); 226 } 227 228 unsigned deviceBlockSize() const 229 { 230 return mon.deviceBlockSizeSlave(); 231 } 232 233 AddrRangeList getAddrRanges() 234 { 235 return mon.getAddrRanges(); 236 } 237 238 void recvRetry() 239 { 240 mon.recvRetrySlave(); 241 } 242 243 private: 244 245 CommMonitor& mon; 246 247 }; 248 249 /** Instance of slave port, i.e. on the CPU side */ 250 MonitorSlavePort slavePort; 251 252 void recvFunctional(PacketPtr pkt); 253 254 void recvFunctionalSnoop(PacketPtr pkt); 255 256 Tick recvAtomic(PacketPtr pkt); 257 258 Tick recvAtomicSnoop(PacketPtr pkt); 259 260 bool recvTimingReq(PacketPtr pkt); 261 262 bool recvTimingResp(PacketPtr pkt); 263 264 void recvTimingSnoopReq(PacketPtr pkt); 265 266 bool recvTimingSnoopResp(PacketPtr pkt); 267 268 unsigned deviceBlockSizeMaster(); 269 270 unsigned deviceBlockSizeSlave(); 271 272 AddrRangeList getAddrRanges(); 273 274 bool isSnooping() const; 275 276 void recvRetryMaster(); 277 278 void recvRetrySlave(); 279 280 void recvRangeChange(); 281 282 void periodicTraceDump(); 283 284 /** Stats declarations, all in a struct for convenience. */ 285 struct MonitorStats 286 { 287 288 /** Disable flag for burst length historgrams **/ 289 bool disableBurstLengthHists; 290 291 /** Histogram of read burst lengths */ 292 Stats::Histogram readBurstLengthHist; 293 294 /** Histogram of write burst lengths */ 295 Stats::Histogram writeBurstLengthHist; 296 297 /** Disable flag for the bandwidth histograms */ 298 bool disableBandwidthHists; 299 300 /** 301 * Histogram for read bandwidth per sample window. The 302 * internal counter is an unsigned int rather than a stat. 303 */ 304 unsigned int readBytes; 305 Stats::Histogram readBandwidthHist; 306 Stats::Formula averageReadBW; 307 Stats::Scalar totalReadBytes; 308 309 /** 310 * Histogram for write bandwidth per sample window. The 311 * internal counter is an unsigned int rather than a stat. 312 */ 313 unsigned int writtenBytes; 314 Stats::Histogram writeBandwidthHist; 315 Stats::Formula averageWriteBW; 316 Stats::Scalar totalWrittenBytes; 317 318 /** Disable flag for latency histograms. */ 319 bool disableLatencyHists; 320 321 /** Histogram of read request-to-response latencies */ 322 Stats::Histogram readLatencyHist; 323 324 /** Histogram of write request-to-response latencies */ 325 Stats::Histogram writeLatencyHist; 326 327 /** Disable flag for ITT distributions. */ 328 bool disableITTDists; 329 330 /** 331 * Inter transaction time (ITT) distributions. There are 332 * histograms of the time between two read, write or arbitrary 333 * accesses. The time of a request is the tick at which the 334 * request is forwarded by the monitor. 335 */ 336 Stats::Distribution ittReadRead; 337 Stats::Distribution ittWriteWrite; 338 Stats::Distribution ittReqReq; 339 Tick timeOfLastRead; 340 Tick timeOfLastWrite; 341 Tick timeOfLastReq; 342 343 /** Disable flag for outstanding histograms. */ 344 bool disableOutstandingHists; 345 346 /** 347 * Histogram of outstanding read requests. Counter for 348 * outstanding read requests is an unsigned integer because 349 * it should not be reset when stats are reset. 350 */ 351 Stats::Histogram outstandingReadsHist; 352 unsigned int outstandingReadReqs; 353 354 /** 355 * Histogram of outstanding write requests. Counter for 356 * outstanding write requests is an unsigned integer because 357 * it should not be reset when stats are reset. 358 */ 359 Stats::Histogram outstandingWritesHist; 360 unsigned int outstandingWriteReqs; 361 362 /** Disable flag for transaction histograms. */ 363 bool disableTransactionHists; 364 365 /** Histogram of number of read transactions per time bin */ 366 Stats::Histogram readTransHist; 367 unsigned int readTrans; 368 369 /** Histogram of number of timing write transactions per time bin */ 370 Stats::Histogram writeTransHist; 371 unsigned int writeTrans; 372 373 /** Disable flag for address distributions. */ 374 bool disableAddrDists; 375 376 /** 377 * Histogram of number of read accesses to addresses over 378 * time. 379 */ 380 Stats::SparseHistogram readAddrDist; 381 382 /** 383 * Histogram of number of write accesses to addresses over 384 * time. 385 */ 386 Stats::SparseHistogram writeAddrDist; 387 388 /** 389 * Create the monitor stats and initialise all the members 390 * that are not statistics themselves, but used to control the 391 * stats or track values during a sample period. 392 */ 393 MonitorStats(const CommMonitorParams* params) : 394 disableBurstLengthHists(params->disable_burst_length_hists), 395 disableBandwidthHists(params->disable_bandwidth_hists), 396 readBytes(0), writtenBytes(0), 397 disableLatencyHists(params->disable_latency_hists), 398 disableITTDists(params->disable_itt_dists), 399 timeOfLastRead(0), timeOfLastWrite(0), timeOfLastReq(0), 400 disableOutstandingHists(params->disable_outstanding_hists), 401 outstandingReadReqs(0), outstandingWriteReqs(0), 402 disableTransactionHists(params->disable_transaction_hists), 403 readTrans(0), writeTrans(0), 404 disableAddrDists(params->disable_addr_dists) 405 { } 406 407 }; 408 409 /** This function is called periodically at the end of each time bin */ 410 void samplePeriodic(); 411 412 /** Schedule the first periodic event */ 413 void startup(); 414 415 /** Periodic event called at the end of each simulation time bin */ 416 EventWrapper<CommMonitor, &CommMonitor::samplePeriodic> samplePeriodicEvent; 417 418 /** Length of simulation time bin*/ 419 Tick samplePeriodTicks; 420 Time samplePeriod; 421 422 /** Address mask for sources of read accesses to be captured */ 423 Addr readAddrMask; 424 425 /** Address mask for sources of write accesses to be captured */ 426 Addr writeAddrMask; 427 428 /** Instantiate stats */ 429 MonitorStats stats; 430}; 431 432#endif //__MEM_COMM_MONITOR_HH__ 433