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