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