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