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