base.cc revision 10887:279efb97ec99
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 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} 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] + \ 193 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq]) 194 195// should writebacks be included here? prior code was inconsistent... 196#define SUM_NON_DEMAND(s) \ 197 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 198 199 demandHits 200 .name(name() + ".demand_hits") 201 .desc("number of demand (read+write) hits") 202 .flags(total | nozero | nonan) 203 ; 204 demandHits = SUM_DEMAND(hits); 205 for (int i = 0; i < system->maxMasters(); i++) { 206 demandHits.subname(i, system->getMasterName(i)); 207 } 208 209 overallHits 210 .name(name() + ".overall_hits") 211 .desc("number of overall hits") 212 .flags(total | nozero | nonan) 213 ; 214 overallHits = demandHits + SUM_NON_DEMAND(hits); 215 for (int i = 0; i < system->maxMasters(); i++) { 216 overallHits.subname(i, system->getMasterName(i)); 217 } 218 219 // Miss statistics 220 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 221 MemCmd cmd(access_idx); 222 const string &cstr = cmd.toString(); 223 224 misses[access_idx] 225 .init(system->maxMasters()) 226 .name(name() + "." + cstr + "_misses") 227 .desc("number of " + cstr + " misses") 228 .flags(total | nozero | nonan) 229 ; 230 for (int i = 0; i < system->maxMasters(); i++) { 231 misses[access_idx].subname(i, system->getMasterName(i)); 232 } 233 } 234 235 demandMisses 236 .name(name() + ".demand_misses") 237 .desc("number of demand (read+write) misses") 238 .flags(total | nozero | nonan) 239 ; 240 demandMisses = SUM_DEMAND(misses); 241 for (int i = 0; i < system->maxMasters(); i++) { 242 demandMisses.subname(i, system->getMasterName(i)); 243 } 244 245 overallMisses 246 .name(name() + ".overall_misses") 247 .desc("number of overall misses") 248 .flags(total | nozero | nonan) 249 ; 250 overallMisses = demandMisses + SUM_NON_DEMAND(misses); 251 for (int i = 0; i < system->maxMasters(); i++) { 252 overallMisses.subname(i, system->getMasterName(i)); 253 } 254 255 // Miss latency statistics 256 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 257 MemCmd cmd(access_idx); 258 const string &cstr = cmd.toString(); 259 260 missLatency[access_idx] 261 .init(system->maxMasters()) 262 .name(name() + "." + cstr + "_miss_latency") 263 .desc("number of " + cstr + " miss cycles") 264 .flags(total | nozero | nonan) 265 ; 266 for (int i = 0; i < system->maxMasters(); i++) { 267 missLatency[access_idx].subname(i, system->getMasterName(i)); 268 } 269 } 270 271 demandMissLatency 272 .name(name() + ".demand_miss_latency") 273 .desc("number of demand (read+write) miss cycles") 274 .flags(total | nozero | nonan) 275 ; 276 demandMissLatency = SUM_DEMAND(missLatency); 277 for (int i = 0; i < system->maxMasters(); i++) { 278 demandMissLatency.subname(i, system->getMasterName(i)); 279 } 280 281 overallMissLatency 282 .name(name() + ".overall_miss_latency") 283 .desc("number of overall miss cycles") 284 .flags(total | nozero | nonan) 285 ; 286 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 287 for (int i = 0; i < system->maxMasters(); i++) { 288 overallMissLatency.subname(i, system->getMasterName(i)); 289 } 290 291 // access formulas 292 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 293 MemCmd cmd(access_idx); 294 const string &cstr = cmd.toString(); 295 296 accesses[access_idx] 297 .name(name() + "." + cstr + "_accesses") 298 .desc("number of " + cstr + " accesses(hits+misses)") 299 .flags(total | nozero | nonan) 300 ; 301 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 302 303 for (int i = 0; i < system->maxMasters(); i++) { 304 accesses[access_idx].subname(i, system->getMasterName(i)); 305 } 306 } 307 308 demandAccesses 309 .name(name() + ".demand_accesses") 310 .desc("number of demand (read+write) accesses") 311 .flags(total | nozero | nonan) 312 ; 313 demandAccesses = demandHits + demandMisses; 314 for (int i = 0; i < system->maxMasters(); i++) { 315 demandAccesses.subname(i, system->getMasterName(i)); 316 } 317 318 overallAccesses 319 .name(name() + ".overall_accesses") 320 .desc("number of overall (read+write) accesses") 321 .flags(total | nozero | nonan) 322 ; 323 overallAccesses = overallHits + overallMisses; 324 for (int i = 0; i < system->maxMasters(); i++) { 325 overallAccesses.subname(i, system->getMasterName(i)); 326 } 327 328 // miss rate formulas 329 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 330 MemCmd cmd(access_idx); 331 const string &cstr = cmd.toString(); 332 333 missRate[access_idx] 334 .name(name() + "." + cstr + "_miss_rate") 335 .desc("miss rate for " + cstr + " accesses") 336 .flags(total | nozero | nonan) 337 ; 338 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 339 340 for (int i = 0; i < system->maxMasters(); i++) { 341 missRate[access_idx].subname(i, system->getMasterName(i)); 342 } 343 } 344 345 demandMissRate 346 .name(name() + ".demand_miss_rate") 347 .desc("miss rate for demand accesses") 348 .flags(total | nozero | nonan) 349 ; 350 demandMissRate = demandMisses / demandAccesses; 351 for (int i = 0; i < system->maxMasters(); i++) { 352 demandMissRate.subname(i, system->getMasterName(i)); 353 } 354 355 overallMissRate 356 .name(name() + ".overall_miss_rate") 357 .desc("miss rate for overall accesses") 358 .flags(total | nozero | nonan) 359 ; 360 overallMissRate = overallMisses / overallAccesses; 361 for (int i = 0; i < system->maxMasters(); i++) { 362 overallMissRate.subname(i, system->getMasterName(i)); 363 } 364 365 // miss latency formulas 366 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 367 MemCmd cmd(access_idx); 368 const string &cstr = cmd.toString(); 369 370 avgMissLatency[access_idx] 371 .name(name() + "." + cstr + "_avg_miss_latency") 372 .desc("average " + cstr + " miss latency") 373 .flags(total | nozero | nonan) 374 ; 375 avgMissLatency[access_idx] = 376 missLatency[access_idx] / misses[access_idx]; 377 378 for (int i = 0; i < system->maxMasters(); i++) { 379 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 380 } 381 } 382 383 demandAvgMissLatency 384 .name(name() + ".demand_avg_miss_latency") 385 .desc("average overall miss latency") 386 .flags(total | nozero | nonan) 387 ; 388 demandAvgMissLatency = demandMissLatency / demandMisses; 389 for (int i = 0; i < system->maxMasters(); i++) { 390 demandAvgMissLatency.subname(i, system->getMasterName(i)); 391 } 392 393 overallAvgMissLatency 394 .name(name() + ".overall_avg_miss_latency") 395 .desc("average overall miss latency") 396 .flags(total | nozero | nonan) 397 ; 398 overallAvgMissLatency = overallMissLatency / overallMisses; 399 for (int i = 0; i < system->maxMasters(); i++) { 400 overallAvgMissLatency.subname(i, system->getMasterName(i)); 401 } 402 403 blocked_cycles.init(NUM_BLOCKED_CAUSES); 404 blocked_cycles 405 .name(name() + ".blocked_cycles") 406 .desc("number of cycles access was blocked") 407 .subname(Blocked_NoMSHRs, "no_mshrs") 408 .subname(Blocked_NoTargets, "no_targets") 409 ; 410 411 412 blocked_causes.init(NUM_BLOCKED_CAUSES); 413 blocked_causes 414 .name(name() + ".blocked") 415 .desc("number of cycles access was blocked") 416 .subname(Blocked_NoMSHRs, "no_mshrs") 417 .subname(Blocked_NoTargets, "no_targets") 418 ; 419 420 avg_blocked 421 .name(name() + ".avg_blocked_cycles") 422 .desc("average number of cycles each access was blocked") 423 .subname(Blocked_NoMSHRs, "no_mshrs") 424 .subname(Blocked_NoTargets, "no_targets") 425 ; 426 427 avg_blocked = blocked_cycles / blocked_causes; 428 429 fastWrites 430 .name(name() + ".fast_writes") 431 .desc("number of fast writes performed") 432 ; 433 434 cacheCopies 435 .name(name() + ".cache_copies") 436 .desc("number of cache copies performed") 437 ; 438 439 writebacks 440 .init(system->maxMasters()) 441 .name(name() + ".writebacks") 442 .desc("number of writebacks") 443 .flags(total | nozero | nonan) 444 ; 445 for (int i = 0; i < system->maxMasters(); i++) { 446 writebacks.subname(i, system->getMasterName(i)); 447 } 448 449 // MSHR statistics 450 // MSHR hit statistics 451 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 452 MemCmd cmd(access_idx); 453 const string &cstr = cmd.toString(); 454 455 mshr_hits[access_idx] 456 .init(system->maxMasters()) 457 .name(name() + "." + cstr + "_mshr_hits") 458 .desc("number of " + cstr + " MSHR hits") 459 .flags(total | nozero | nonan) 460 ; 461 for (int i = 0; i < system->maxMasters(); i++) { 462 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 463 } 464 } 465 466 demandMshrHits 467 .name(name() + ".demand_mshr_hits") 468 .desc("number of demand (read+write) MSHR hits") 469 .flags(total | nozero | nonan) 470 ; 471 demandMshrHits = SUM_DEMAND(mshr_hits); 472 for (int i = 0; i < system->maxMasters(); i++) { 473 demandMshrHits.subname(i, system->getMasterName(i)); 474 } 475 476 overallMshrHits 477 .name(name() + ".overall_mshr_hits") 478 .desc("number of overall MSHR hits") 479 .flags(total | nozero | nonan) 480 ; 481 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 482 for (int i = 0; i < system->maxMasters(); i++) { 483 overallMshrHits.subname(i, system->getMasterName(i)); 484 } 485 486 // MSHR miss statistics 487 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 488 MemCmd cmd(access_idx); 489 const string &cstr = cmd.toString(); 490 491 mshr_misses[access_idx] 492 .init(system->maxMasters()) 493 .name(name() + "." + cstr + "_mshr_misses") 494 .desc("number of " + cstr + " MSHR misses") 495 .flags(total | nozero | nonan) 496 ; 497 for (int i = 0; i < system->maxMasters(); i++) { 498 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 499 } 500 } 501 502 demandMshrMisses 503 .name(name() + ".demand_mshr_misses") 504 .desc("number of demand (read+write) MSHR misses") 505 .flags(total | nozero | nonan) 506 ; 507 demandMshrMisses = SUM_DEMAND(mshr_misses); 508 for (int i = 0; i < system->maxMasters(); i++) { 509 demandMshrMisses.subname(i, system->getMasterName(i)); 510 } 511 512 overallMshrMisses 513 .name(name() + ".overall_mshr_misses") 514 .desc("number of overall MSHR misses") 515 .flags(total | nozero | nonan) 516 ; 517 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 518 for (int i = 0; i < system->maxMasters(); i++) { 519 overallMshrMisses.subname(i, system->getMasterName(i)); 520 } 521 522 // MSHR miss latency statistics 523 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 524 MemCmd cmd(access_idx); 525 const string &cstr = cmd.toString(); 526 527 mshr_miss_latency[access_idx] 528 .init(system->maxMasters()) 529 .name(name() + "." + cstr + "_mshr_miss_latency") 530 .desc("number of " + cstr + " MSHR miss cycles") 531 .flags(total | nozero | nonan) 532 ; 533 for (int i = 0; i < system->maxMasters(); i++) { 534 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 535 } 536 } 537 538 demandMshrMissLatency 539 .name(name() + ".demand_mshr_miss_latency") 540 .desc("number of demand (read+write) MSHR miss cycles") 541 .flags(total | nozero | nonan) 542 ; 543 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 544 for (int i = 0; i < system->maxMasters(); i++) { 545 demandMshrMissLatency.subname(i, system->getMasterName(i)); 546 } 547 548 overallMshrMissLatency 549 .name(name() + ".overall_mshr_miss_latency") 550 .desc("number of overall MSHR miss cycles") 551 .flags(total | nozero | nonan) 552 ; 553 overallMshrMissLatency = 554 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 555 for (int i = 0; i < system->maxMasters(); i++) { 556 overallMshrMissLatency.subname(i, system->getMasterName(i)); 557 } 558 559 // MSHR uncacheable statistics 560 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 561 MemCmd cmd(access_idx); 562 const string &cstr = cmd.toString(); 563 564 mshr_uncacheable[access_idx] 565 .init(system->maxMasters()) 566 .name(name() + "." + cstr + "_mshr_uncacheable") 567 .desc("number of " + cstr + " MSHR uncacheable") 568 .flags(total | nozero | nonan) 569 ; 570 for (int i = 0; i < system->maxMasters(); i++) { 571 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 572 } 573 } 574 575 overallMshrUncacheable 576 .name(name() + ".overall_mshr_uncacheable_misses") 577 .desc("number of overall MSHR uncacheable misses") 578 .flags(total | nozero | nonan) 579 ; 580 overallMshrUncacheable = 581 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 582 for (int i = 0; i < system->maxMasters(); i++) { 583 overallMshrUncacheable.subname(i, system->getMasterName(i)); 584 } 585 586 // MSHR miss latency statistics 587 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 588 MemCmd cmd(access_idx); 589 const string &cstr = cmd.toString(); 590 591 mshr_uncacheable_lat[access_idx] 592 .init(system->maxMasters()) 593 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 594 .desc("number of " + cstr + " MSHR uncacheable cycles") 595 .flags(total | nozero | nonan) 596 ; 597 for (int i = 0; i < system->maxMasters(); i++) { 598 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i)); 599 } 600 } 601 602 overallMshrUncacheableLatency 603 .name(name() + ".overall_mshr_uncacheable_latency") 604 .desc("number of overall MSHR uncacheable cycles") 605 .flags(total | nozero | nonan) 606 ; 607 overallMshrUncacheableLatency = 608 SUM_DEMAND(mshr_uncacheable_lat) + 609 SUM_NON_DEMAND(mshr_uncacheable_lat); 610 for (int i = 0; i < system->maxMasters(); i++) { 611 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 612 } 613 614#if 0 615 // MSHR access formulas 616 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 617 MemCmd cmd(access_idx); 618 const string &cstr = cmd.toString(); 619 620 mshrAccesses[access_idx] 621 .name(name() + "." + cstr + "_mshr_accesses") 622 .desc("number of " + cstr + " mshr accesses(hits+misses)") 623 .flags(total | nozero | nonan) 624 ; 625 mshrAccesses[access_idx] = 626 mshr_hits[access_idx] + mshr_misses[access_idx] 627 + mshr_uncacheable[access_idx]; 628 } 629 630 demandMshrAccesses 631 .name(name() + ".demand_mshr_accesses") 632 .desc("number of demand (read+write) mshr accesses") 633 .flags(total | nozero | nonan) 634 ; 635 demandMshrAccesses = demandMshrHits + demandMshrMisses; 636 637 overallMshrAccesses 638 .name(name() + ".overall_mshr_accesses") 639 .desc("number of overall (read+write) mshr accesses") 640 .flags(total | nozero | nonan) 641 ; 642 overallMshrAccesses = overallMshrHits + overallMshrMisses 643 + overallMshrUncacheable; 644#endif 645 646 // MSHR miss rate formulas 647 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 648 MemCmd cmd(access_idx); 649 const string &cstr = cmd.toString(); 650 651 mshrMissRate[access_idx] 652 .name(name() + "." + cstr + "_mshr_miss_rate") 653 .desc("mshr miss rate for " + cstr + " accesses") 654 .flags(total | nozero | nonan) 655 ; 656 mshrMissRate[access_idx] = 657 mshr_misses[access_idx] / accesses[access_idx]; 658 659 for (int i = 0; i < system->maxMasters(); i++) { 660 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 661 } 662 } 663 664 demandMshrMissRate 665 .name(name() + ".demand_mshr_miss_rate") 666 .desc("mshr miss rate for demand accesses") 667 .flags(total | nozero | nonan) 668 ; 669 demandMshrMissRate = demandMshrMisses / demandAccesses; 670 for (int i = 0; i < system->maxMasters(); i++) { 671 demandMshrMissRate.subname(i, system->getMasterName(i)); 672 } 673 674 overallMshrMissRate 675 .name(name() + ".overall_mshr_miss_rate") 676 .desc("mshr miss rate for overall accesses") 677 .flags(total | nozero | nonan) 678 ; 679 overallMshrMissRate = overallMshrMisses / overallAccesses; 680 for (int i = 0; i < system->maxMasters(); i++) { 681 overallMshrMissRate.subname(i, system->getMasterName(i)); 682 } 683 684 // mshrMiss latency formulas 685 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 686 MemCmd cmd(access_idx); 687 const string &cstr = cmd.toString(); 688 689 avgMshrMissLatency[access_idx] 690 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 691 .desc("average " + cstr + " mshr miss latency") 692 .flags(total | nozero | nonan) 693 ; 694 avgMshrMissLatency[access_idx] = 695 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 696 697 for (int i = 0; i < system->maxMasters(); i++) { 698 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i)); 699 } 700 } 701 702 demandAvgMshrMissLatency 703 .name(name() + ".demand_avg_mshr_miss_latency") 704 .desc("average overall mshr miss latency") 705 .flags(total | nozero | nonan) 706 ; 707 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 708 for (int i = 0; i < system->maxMasters(); i++) { 709 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 710 } 711 712 overallAvgMshrMissLatency 713 .name(name() + ".overall_avg_mshr_miss_latency") 714 .desc("average overall mshr miss latency") 715 .flags(total | nozero | nonan) 716 ; 717 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 718 for (int i = 0; i < system->maxMasters(); i++) { 719 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 720 } 721 722 // mshrUncacheable latency formulas 723 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 724 MemCmd cmd(access_idx); 725 const string &cstr = cmd.toString(); 726 727 avgMshrUncacheableLatency[access_idx] 728 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 729 .desc("average " + cstr + " mshr uncacheable latency") 730 .flags(total | nozero | nonan) 731 ; 732 avgMshrUncacheableLatency[access_idx] = 733 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 734 735 for (int i = 0; i < system->maxMasters(); i++) { 736 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i)); 737 } 738 } 739 740 overallAvgMshrUncacheableLatency 741 .name(name() + ".overall_avg_mshr_uncacheable_latency") 742 .desc("average overall mshr uncacheable latency") 743 .flags(total | nozero | nonan) 744 ; 745 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 746 for (int i = 0; i < system->maxMasters(); i++) { 747 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 748 } 749 750 mshr_cap_events 751 .init(system->maxMasters()) 752 .name(name() + ".mshr_cap_events") 753 .desc("number of times MSHR cap was activated") 754 .flags(total | nozero | nonan) 755 ; 756 for (int i = 0; i < system->maxMasters(); i++) { 757 mshr_cap_events.subname(i, system->getMasterName(i)); 758 } 759 760 //software prefetching stats 761 soft_prefetch_mshr_full 762 .init(system->maxMasters()) 763 .name(name() + ".soft_prefetch_mshr_full") 764 .desc("number of mshr full events for SW prefetching instrutions") 765 .flags(total | nozero | nonan) 766 ; 767 for (int i = 0; i < system->maxMasters(); i++) { 768 soft_prefetch_mshr_full.subname(i, system->getMasterName(i)); 769 } 770 771 mshr_no_allocate_misses 772 .name(name() +".no_allocate_misses") 773 .desc("Number of misses that were no-allocate") 774 ; 775 776} 777 778unsigned int 779BaseCache::drain(DrainManager *dm) 780{ 781 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) + 782 mshrQueue.drain(dm) + writeBuffer.drain(dm); 783 784 // Set status 785 if (count != 0) { 786 setDrainState(Drainable::Draining); 787 DPRINTF(Drain, "Cache not drained\n"); 788 return count; 789 } 790 791 setDrainState(Drainable::Drained); 792 return 0; 793} 794 795BaseCache * 796BaseCacheParams::create() 797{ 798 assert(tags); 799 800 return new Cache(this); 801} 802