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