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