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