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