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