base.cc revision 11722
1/* 2 * Copyright (c) 2012-2013 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 * Copyright (c) 2003-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Erik Hallnor 41 */ 42 43/** 44 * @file 45 * Definition of BaseCache functions. 46 */ 47 48#include "mem/cache/base.hh" 49 50#include "debug/Cache.hh" 51#include "debug/Drain.hh" 52#include "mem/cache/cache.hh" 53#include "mem/cache/mshr.hh" 54#include "mem/cache/tags/fa_lru.hh" 55#include "mem/cache/tags/lru.hh" 56#include "mem/cache/tags/random_repl.hh" 57#include "sim/full_system.hh" 58 59using namespace std; 60 61BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name, 62 BaseCache *_cache, 63 const std::string &_label) 64 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label), 65 blocked(false), mustSendRetry(false), sendRetryEvent(this) 66{ 67} 68 69BaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size) 70 : MemObject(p), 71 cpuSidePort(nullptr), memSidePort(nullptr), 72 mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below 73 writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below 74 blkSize(blk_size), 75 lookupLatency(p->tag_latency), 76 dataLatency(p->data_latency), 77 forwardLatency(p->tag_latency), 78 fillLatency(p->data_latency), 79 responseLatency(p->response_latency), 80 numTarget(p->tgts_per_mshr), 81 forwardSnoops(true), 82 isReadOnly(p->is_read_only), 83 blocked(0), 84 order(0), 85 noTargetMSHR(nullptr), 86 missCount(p->max_miss_count), 87 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()), 88 system(p->system) 89{ 90 // the MSHR queue has no reserve entries as we check the MSHR 91 // queue on every single allocation, whereas the write queue has 92 // as many reserve entries as we have MSHRs, since every MSHR may 93 // eventually require a writeback, and we do not check the write 94 // buffer before committing to an MSHR 95 96 // forward snoops is overridden in init() once we can query 97 // whether the connected master is actually snooping or not 98} 99 100void 101BaseCache::CacheSlavePort::setBlocked() 102{ 103 assert(!blocked); 104 DPRINTF(CachePort, "Port is blocking new requests\n"); 105 blocked = true; 106 // if we already scheduled a retry in this cycle, but it has not yet 107 // happened, cancel it 108 if (sendRetryEvent.scheduled()) { 109 owner.deschedule(sendRetryEvent); 110 DPRINTF(CachePort, "Port descheduled retry\n"); 111 mustSendRetry = true; 112 } 113} 114 115void 116BaseCache::CacheSlavePort::clearBlocked() 117{ 118 assert(blocked); 119 DPRINTF(CachePort, "Port is accepting new requests\n"); 120 blocked = false; 121 if (mustSendRetry) { 122 // @TODO: need to find a better time (next cycle?) 123 owner.schedule(sendRetryEvent, curTick() + 1); 124 } 125} 126 127void 128BaseCache::CacheSlavePort::processSendRetry() 129{ 130 DPRINTF(CachePort, "Port is sending retry\n"); 131 132 // reset the flag and call retry 133 mustSendRetry = false; 134 sendRetryReq(); 135} 136 137void 138BaseCache::init() 139{ 140 if (!cpuSidePort->isConnected() || !memSidePort->isConnected()) 141 fatal("Cache ports on %s are not connected\n", name()); 142 cpuSidePort->sendRangeChange(); 143 forwardSnoops = cpuSidePort->isSnooping(); 144} 145 146BaseMasterPort & 147BaseCache::getMasterPort(const std::string &if_name, PortID idx) 148{ 149 if (if_name == "mem_side") { 150 return *memSidePort; 151 } else { 152 return MemObject::getMasterPort(if_name, idx); 153 } 154} 155 156BaseSlavePort & 157BaseCache::getSlavePort(const std::string &if_name, PortID idx) 158{ 159 if (if_name == "cpu_side") { 160 return *cpuSidePort; 161 } else { 162 return MemObject::getSlavePort(if_name, idx); 163 } 164} 165 166bool 167BaseCache::inRange(Addr addr) const 168{ 169 for (const auto& r : addrRanges) { 170 if (r.contains(addr)) { 171 return true; 172 } 173 } 174 return false; 175} 176 177void 178BaseCache::regStats() 179{ 180 MemObject::regStats(); 181 182 using namespace Stats; 183 184 // Hit statistics 185 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 186 MemCmd cmd(access_idx); 187 const string &cstr = cmd.toString(); 188 189 hits[access_idx] 190 .init(system->maxMasters()) 191 .name(name() + "." + cstr + "_hits") 192 .desc("number of " + cstr + " hits") 193 .flags(total | nozero | nonan) 194 ; 195 for (int i = 0; i < system->maxMasters(); i++) { 196 hits[access_idx].subname(i, system->getMasterName(i)); 197 } 198 } 199 200// These macros make it easier to sum the right subset of commands and 201// to change the subset of commands that are considered "demand" vs 202// "non-demand" 203#define SUM_DEMAND(s) \ 204 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::WriteLineReq] + \ 205 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq]) 206 207// should writebacks be included here? prior code was inconsistent... 208#define SUM_NON_DEMAND(s) \ 209 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 210 211 demandHits 212 .name(name() + ".demand_hits") 213 .desc("number of demand (read+write) hits") 214 .flags(total | nozero | nonan) 215 ; 216 demandHits = SUM_DEMAND(hits); 217 for (int i = 0; i < system->maxMasters(); i++) { 218 demandHits.subname(i, system->getMasterName(i)); 219 } 220 221 overallHits 222 .name(name() + ".overall_hits") 223 .desc("number of overall hits") 224 .flags(total | nozero | nonan) 225 ; 226 overallHits = demandHits + SUM_NON_DEMAND(hits); 227 for (int i = 0; i < system->maxMasters(); i++) { 228 overallHits.subname(i, system->getMasterName(i)); 229 } 230 231 // Miss statistics 232 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 233 MemCmd cmd(access_idx); 234 const string &cstr = cmd.toString(); 235 236 misses[access_idx] 237 .init(system->maxMasters()) 238 .name(name() + "." + cstr + "_misses") 239 .desc("number of " + cstr + " misses") 240 .flags(total | nozero | nonan) 241 ; 242 for (int i = 0; i < system->maxMasters(); i++) { 243 misses[access_idx].subname(i, system->getMasterName(i)); 244 } 245 } 246 247 demandMisses 248 .name(name() + ".demand_misses") 249 .desc("number of demand (read+write) misses") 250 .flags(total | nozero | nonan) 251 ; 252 demandMisses = SUM_DEMAND(misses); 253 for (int i = 0; i < system->maxMasters(); i++) { 254 demandMisses.subname(i, system->getMasterName(i)); 255 } 256 257 overallMisses 258 .name(name() + ".overall_misses") 259 .desc("number of overall misses") 260 .flags(total | nozero | nonan) 261 ; 262 overallMisses = demandMisses + SUM_NON_DEMAND(misses); 263 for (int i = 0; i < system->maxMasters(); i++) { 264 overallMisses.subname(i, system->getMasterName(i)); 265 } 266 267 // Miss latency statistics 268 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 269 MemCmd cmd(access_idx); 270 const string &cstr = cmd.toString(); 271 272 missLatency[access_idx] 273 .init(system->maxMasters()) 274 .name(name() + "." + cstr + "_miss_latency") 275 .desc("number of " + cstr + " miss cycles") 276 .flags(total | nozero | nonan) 277 ; 278 for (int i = 0; i < system->maxMasters(); i++) { 279 missLatency[access_idx].subname(i, system->getMasterName(i)); 280 } 281 } 282 283 demandMissLatency 284 .name(name() + ".demand_miss_latency") 285 .desc("number of demand (read+write) miss cycles") 286 .flags(total | nozero | nonan) 287 ; 288 demandMissLatency = SUM_DEMAND(missLatency); 289 for (int i = 0; i < system->maxMasters(); i++) { 290 demandMissLatency.subname(i, system->getMasterName(i)); 291 } 292 293 overallMissLatency 294 .name(name() + ".overall_miss_latency") 295 .desc("number of overall miss cycles") 296 .flags(total | nozero | nonan) 297 ; 298 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 299 for (int i = 0; i < system->maxMasters(); i++) { 300 overallMissLatency.subname(i, system->getMasterName(i)); 301 } 302 303 // access formulas 304 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 305 MemCmd cmd(access_idx); 306 const string &cstr = cmd.toString(); 307 308 accesses[access_idx] 309 .name(name() + "." + cstr + "_accesses") 310 .desc("number of " + cstr + " accesses(hits+misses)") 311 .flags(total | nozero | nonan) 312 ; 313 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 314 315 for (int i = 0; i < system->maxMasters(); i++) { 316 accesses[access_idx].subname(i, system->getMasterName(i)); 317 } 318 } 319 320 demandAccesses 321 .name(name() + ".demand_accesses") 322 .desc("number of demand (read+write) accesses") 323 .flags(total | nozero | nonan) 324 ; 325 demandAccesses = demandHits + demandMisses; 326 for (int i = 0; i < system->maxMasters(); i++) { 327 demandAccesses.subname(i, system->getMasterName(i)); 328 } 329 330 overallAccesses 331 .name(name() + ".overall_accesses") 332 .desc("number of overall (read+write) accesses") 333 .flags(total | nozero | nonan) 334 ; 335 overallAccesses = overallHits + overallMisses; 336 for (int i = 0; i < system->maxMasters(); i++) { 337 overallAccesses.subname(i, system->getMasterName(i)); 338 } 339 340 // miss rate formulas 341 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 342 MemCmd cmd(access_idx); 343 const string &cstr = cmd.toString(); 344 345 missRate[access_idx] 346 .name(name() + "." + cstr + "_miss_rate") 347 .desc("miss rate for " + cstr + " accesses") 348 .flags(total | nozero | nonan) 349 ; 350 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 351 352 for (int i = 0; i < system->maxMasters(); i++) { 353 missRate[access_idx].subname(i, system->getMasterName(i)); 354 } 355 } 356 357 demandMissRate 358 .name(name() + ".demand_miss_rate") 359 .desc("miss rate for demand accesses") 360 .flags(total | nozero | nonan) 361 ; 362 demandMissRate = demandMisses / demandAccesses; 363 for (int i = 0; i < system->maxMasters(); i++) { 364 demandMissRate.subname(i, system->getMasterName(i)); 365 } 366 367 overallMissRate 368 .name(name() + ".overall_miss_rate") 369 .desc("miss rate for overall accesses") 370 .flags(total | nozero | nonan) 371 ; 372 overallMissRate = overallMisses / overallAccesses; 373 for (int i = 0; i < system->maxMasters(); i++) { 374 overallMissRate.subname(i, system->getMasterName(i)); 375 } 376 377 // miss latency formulas 378 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 379 MemCmd cmd(access_idx); 380 const string &cstr = cmd.toString(); 381 382 avgMissLatency[access_idx] 383 .name(name() + "." + cstr + "_avg_miss_latency") 384 .desc("average " + cstr + " miss latency") 385 .flags(total | nozero | nonan) 386 ; 387 avgMissLatency[access_idx] = 388 missLatency[access_idx] / misses[access_idx]; 389 390 for (int i = 0; i < system->maxMasters(); i++) { 391 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 392 } 393 } 394 395 demandAvgMissLatency 396 .name(name() + ".demand_avg_miss_latency") 397 .desc("average overall miss latency") 398 .flags(total | nozero | nonan) 399 ; 400 demandAvgMissLatency = demandMissLatency / demandMisses; 401 for (int i = 0; i < system->maxMasters(); i++) { 402 demandAvgMissLatency.subname(i, system->getMasterName(i)); 403 } 404 405 overallAvgMissLatency 406 .name(name() + ".overall_avg_miss_latency") 407 .desc("average overall miss latency") 408 .flags(total | nozero | nonan) 409 ; 410 overallAvgMissLatency = overallMissLatency / overallMisses; 411 for (int i = 0; i < system->maxMasters(); i++) { 412 overallAvgMissLatency.subname(i, system->getMasterName(i)); 413 } 414 415 blocked_cycles.init(NUM_BLOCKED_CAUSES); 416 blocked_cycles 417 .name(name() + ".blocked_cycles") 418 .desc("number of cycles access was blocked") 419 .subname(Blocked_NoMSHRs, "no_mshrs") 420 .subname(Blocked_NoTargets, "no_targets") 421 ; 422 423 424 blocked_causes.init(NUM_BLOCKED_CAUSES); 425 blocked_causes 426 .name(name() + ".blocked") 427 .desc("number of cycles access was blocked") 428 .subname(Blocked_NoMSHRs, "no_mshrs") 429 .subname(Blocked_NoTargets, "no_targets") 430 ; 431 432 avg_blocked 433 .name(name() + ".avg_blocked_cycles") 434 .desc("average number of cycles each access was blocked") 435 .subname(Blocked_NoMSHRs, "no_mshrs") 436 .subname(Blocked_NoTargets, "no_targets") 437 ; 438 439 avg_blocked = blocked_cycles / blocked_causes; 440 441 unusedPrefetches 442 .name(name() + ".unused_prefetches") 443 .desc("number of HardPF blocks evicted w/o reference") 444 .flags(nozero) 445 ; 446 447 writebacks 448 .init(system->maxMasters()) 449 .name(name() + ".writebacks") 450 .desc("number of writebacks") 451 .flags(total | nozero | nonan) 452 ; 453 for (int i = 0; i < system->maxMasters(); i++) { 454 writebacks.subname(i, system->getMasterName(i)); 455 } 456 457 // MSHR statistics 458 // MSHR hit statistics 459 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 460 MemCmd cmd(access_idx); 461 const string &cstr = cmd.toString(); 462 463 mshr_hits[access_idx] 464 .init(system->maxMasters()) 465 .name(name() + "." + cstr + "_mshr_hits") 466 .desc("number of " + cstr + " MSHR hits") 467 .flags(total | nozero | nonan) 468 ; 469 for (int i = 0; i < system->maxMasters(); i++) { 470 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 471 } 472 } 473 474 demandMshrHits 475 .name(name() + ".demand_mshr_hits") 476 .desc("number of demand (read+write) MSHR hits") 477 .flags(total | nozero | nonan) 478 ; 479 demandMshrHits = SUM_DEMAND(mshr_hits); 480 for (int i = 0; i < system->maxMasters(); i++) { 481 demandMshrHits.subname(i, system->getMasterName(i)); 482 } 483 484 overallMshrHits 485 .name(name() + ".overall_mshr_hits") 486 .desc("number of overall MSHR hits") 487 .flags(total | nozero | nonan) 488 ; 489 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 490 for (int i = 0; i < system->maxMasters(); i++) { 491 overallMshrHits.subname(i, system->getMasterName(i)); 492 } 493 494 // MSHR miss statistics 495 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 496 MemCmd cmd(access_idx); 497 const string &cstr = cmd.toString(); 498 499 mshr_misses[access_idx] 500 .init(system->maxMasters()) 501 .name(name() + "." + cstr + "_mshr_misses") 502 .desc("number of " + cstr + " MSHR misses") 503 .flags(total | nozero | nonan) 504 ; 505 for (int i = 0; i < system->maxMasters(); i++) { 506 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 507 } 508 } 509 510 demandMshrMisses 511 .name(name() + ".demand_mshr_misses") 512 .desc("number of demand (read+write) MSHR misses") 513 .flags(total | nozero | nonan) 514 ; 515 demandMshrMisses = SUM_DEMAND(mshr_misses); 516 for (int i = 0; i < system->maxMasters(); i++) { 517 demandMshrMisses.subname(i, system->getMasterName(i)); 518 } 519 520 overallMshrMisses 521 .name(name() + ".overall_mshr_misses") 522 .desc("number of overall MSHR misses") 523 .flags(total | nozero | nonan) 524 ; 525 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 526 for (int i = 0; i < system->maxMasters(); i++) { 527 overallMshrMisses.subname(i, system->getMasterName(i)); 528 } 529 530 // MSHR miss latency statistics 531 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 532 MemCmd cmd(access_idx); 533 const string &cstr = cmd.toString(); 534 535 mshr_miss_latency[access_idx] 536 .init(system->maxMasters()) 537 .name(name() + "." + cstr + "_mshr_miss_latency") 538 .desc("number of " + cstr + " MSHR miss cycles") 539 .flags(total | nozero | nonan) 540 ; 541 for (int i = 0; i < system->maxMasters(); i++) { 542 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 543 } 544 } 545 546 demandMshrMissLatency 547 .name(name() + ".demand_mshr_miss_latency") 548 .desc("number of demand (read+write) MSHR miss cycles") 549 .flags(total | nozero | nonan) 550 ; 551 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 552 for (int i = 0; i < system->maxMasters(); i++) { 553 demandMshrMissLatency.subname(i, system->getMasterName(i)); 554 } 555 556 overallMshrMissLatency 557 .name(name() + ".overall_mshr_miss_latency") 558 .desc("number of overall MSHR miss cycles") 559 .flags(total | nozero | nonan) 560 ; 561 overallMshrMissLatency = 562 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 563 for (int i = 0; i < system->maxMasters(); i++) { 564 overallMshrMissLatency.subname(i, system->getMasterName(i)); 565 } 566 567 // MSHR uncacheable statistics 568 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 569 MemCmd cmd(access_idx); 570 const string &cstr = cmd.toString(); 571 572 mshr_uncacheable[access_idx] 573 .init(system->maxMasters()) 574 .name(name() + "." + cstr + "_mshr_uncacheable") 575 .desc("number of " + cstr + " MSHR uncacheable") 576 .flags(total | nozero | nonan) 577 ; 578 for (int i = 0; i < system->maxMasters(); i++) { 579 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 580 } 581 } 582 583 overallMshrUncacheable 584 .name(name() + ".overall_mshr_uncacheable_misses") 585 .desc("number of overall MSHR uncacheable misses") 586 .flags(total | nozero | nonan) 587 ; 588 overallMshrUncacheable = 589 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 590 for (int i = 0; i < system->maxMasters(); i++) { 591 overallMshrUncacheable.subname(i, system->getMasterName(i)); 592 } 593 594 // MSHR miss latency statistics 595 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 596 MemCmd cmd(access_idx); 597 const string &cstr = cmd.toString(); 598 599 mshr_uncacheable_lat[access_idx] 600 .init(system->maxMasters()) 601 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 602 .desc("number of " + cstr + " MSHR uncacheable cycles") 603 .flags(total | nozero | nonan) 604 ; 605 for (int i = 0; i < system->maxMasters(); i++) { 606 mshr_uncacheable_lat[access_idx].subname( 607 i, system->getMasterName(i)); 608 } 609 } 610 611 overallMshrUncacheableLatency 612 .name(name() + ".overall_mshr_uncacheable_latency") 613 .desc("number of overall MSHR uncacheable cycles") 614 .flags(total | nozero | nonan) 615 ; 616 overallMshrUncacheableLatency = 617 SUM_DEMAND(mshr_uncacheable_lat) + 618 SUM_NON_DEMAND(mshr_uncacheable_lat); 619 for (int i = 0; i < system->maxMasters(); i++) { 620 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 621 } 622 623#if 0 624 // MSHR access formulas 625 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 626 MemCmd cmd(access_idx); 627 const string &cstr = cmd.toString(); 628 629 mshrAccesses[access_idx] 630 .name(name() + "." + cstr + "_mshr_accesses") 631 .desc("number of " + cstr + " mshr accesses(hits+misses)") 632 .flags(total | nozero | nonan) 633 ; 634 mshrAccesses[access_idx] = 635 mshr_hits[access_idx] + mshr_misses[access_idx] 636 + mshr_uncacheable[access_idx]; 637 } 638 639 demandMshrAccesses 640 .name(name() + ".demand_mshr_accesses") 641 .desc("number of demand (read+write) mshr accesses") 642 .flags(total | nozero | nonan) 643 ; 644 demandMshrAccesses = demandMshrHits + demandMshrMisses; 645 646 overallMshrAccesses 647 .name(name() + ".overall_mshr_accesses") 648 .desc("number of overall (read+write) mshr accesses") 649 .flags(total | nozero | nonan) 650 ; 651 overallMshrAccesses = overallMshrHits + overallMshrMisses 652 + overallMshrUncacheable; 653#endif 654 655 // MSHR miss rate formulas 656 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 657 MemCmd cmd(access_idx); 658 const string &cstr = cmd.toString(); 659 660 mshrMissRate[access_idx] 661 .name(name() + "." + cstr + "_mshr_miss_rate") 662 .desc("mshr miss rate for " + cstr + " accesses") 663 .flags(total | nozero | nonan) 664 ; 665 mshrMissRate[access_idx] = 666 mshr_misses[access_idx] / accesses[access_idx]; 667 668 for (int i = 0; i < system->maxMasters(); i++) { 669 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 670 } 671 } 672 673 demandMshrMissRate 674 .name(name() + ".demand_mshr_miss_rate") 675 .desc("mshr miss rate for demand accesses") 676 .flags(total | nozero | nonan) 677 ; 678 demandMshrMissRate = demandMshrMisses / demandAccesses; 679 for (int i = 0; i < system->maxMasters(); i++) { 680 demandMshrMissRate.subname(i, system->getMasterName(i)); 681 } 682 683 overallMshrMissRate 684 .name(name() + ".overall_mshr_miss_rate") 685 .desc("mshr miss rate for overall accesses") 686 .flags(total | nozero | nonan) 687 ; 688 overallMshrMissRate = overallMshrMisses / overallAccesses; 689 for (int i = 0; i < system->maxMasters(); i++) { 690 overallMshrMissRate.subname(i, system->getMasterName(i)); 691 } 692 693 // mshrMiss latency formulas 694 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 695 MemCmd cmd(access_idx); 696 const string &cstr = cmd.toString(); 697 698 avgMshrMissLatency[access_idx] 699 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 700 .desc("average " + cstr + " mshr miss latency") 701 .flags(total | nozero | nonan) 702 ; 703 avgMshrMissLatency[access_idx] = 704 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 705 706 for (int i = 0; i < system->maxMasters(); i++) { 707 avgMshrMissLatency[access_idx].subname( 708 i, system->getMasterName(i)); 709 } 710 } 711 712 demandAvgMshrMissLatency 713 .name(name() + ".demand_avg_mshr_miss_latency") 714 .desc("average overall mshr miss latency") 715 .flags(total | nozero | nonan) 716 ; 717 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 718 for (int i = 0; i < system->maxMasters(); i++) { 719 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 720 } 721 722 overallAvgMshrMissLatency 723 .name(name() + ".overall_avg_mshr_miss_latency") 724 .desc("average overall mshr miss latency") 725 .flags(total | nozero | nonan) 726 ; 727 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 728 for (int i = 0; i < system->maxMasters(); i++) { 729 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 730 } 731 732 // mshrUncacheable latency formulas 733 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 734 MemCmd cmd(access_idx); 735 const string &cstr = cmd.toString(); 736 737 avgMshrUncacheableLatency[access_idx] 738 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 739 .desc("average " + cstr + " mshr uncacheable latency") 740 .flags(total | nozero | nonan) 741 ; 742 avgMshrUncacheableLatency[access_idx] = 743 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 744 745 for (int i = 0; i < system->maxMasters(); i++) { 746 avgMshrUncacheableLatency[access_idx].subname( 747 i, system->getMasterName(i)); 748 } 749 } 750 751 overallAvgMshrUncacheableLatency 752 .name(name() + ".overall_avg_mshr_uncacheable_latency") 753 .desc("average overall mshr uncacheable latency") 754 .flags(total | nozero | nonan) 755 ; 756 overallAvgMshrUncacheableLatency = 757 overallMshrUncacheableLatency / overallMshrUncacheable; 758 for (int i = 0; i < system->maxMasters(); i++) { 759 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 760 } 761 762} 763