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