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