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