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