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