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