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