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