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