base.cc revision 11484
12SN/A/* 21762SN/A * Copyright (c) 2012-2013 ARM Limited 32SN/A * All rights reserved. 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 152SN/A * All rights reserved. 162SN/A * 172SN/A * Redistribution and use in source and binary forms, with or without 182SN/A * modification, are permitted provided that the following conditions are 192SN/A * met: redistributions of source code must retain the above copyright 202SN/A * notice, this list of conditions and the following disclaimer; 212SN/A * redistributions in binary form must reproduce the above copyright 222SN/A * notice, this list of conditions and the following disclaimer in the 232SN/A * documentation and/or other materials provided with the distribution; 242SN/A * neither the name of the copyright holders nor the names of its 252SN/A * contributors may be used to endorse or promote products derived from 262SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352147SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367678Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 378229Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387878Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392147SN/A * 402147SN/A * Authors: Erik Hallnor 412680Sktlim@umich.edu */ 422132SN/A 432147SN/A/** 445999Snate@binkert.org * @file 452147SN/A * Definition of BaseCache functions. 462147SN/A */ 472147SN/A 482147SN/A#include "debug/Cache.hh" 492147SN/A#include "debug/Drain.hh" 502147SN/A#include "mem/cache/tags/fa_lru.hh" 512147SN/A#include "mem/cache/tags/lru.hh" 522147SN/A#include "mem/cache/tags/random_repl.hh" 532147SN/A#include "mem/cache/base.hh" 542090SN/A#include "mem/cache/cache.hh" 552147SN/A#include "mem/cache/mshr.hh" 564695Sgblack@eecs.umich.edu#include "sim/full_system.hh" 5710417Sandreas.hansson@arm.com 5810417Sandreas.hansson@arm.comusing namespace std; 592SN/A 602SN/ABaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name, 612612SN/A BaseCache *_cache, 622612SN/A const std::string &_label) 632612SN/A : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label), 642612SN/A blocked(false), mustSendRetry(false), sendRetryEvent(this) 652612SN/A{ 662612SN/A} 672612SN/A 682612SN/ABaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size) 692612SN/A : MemObject(p), 704695Sgblack@eecs.umich.edu cpuSidePort(nullptr), memSidePort(nullptr), 7110417Sandreas.hansson@arm.com mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below 7210417Sandreas.hansson@arm.com writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below 732612SN/A blkSize(blk_size), 742612SN/A lookupLatency(p->hit_latency), 758545Ssaidi@eecs.umich.edu forwardLatency(p->hit_latency), 768545Ssaidi@eecs.umich.edu fillLatency(p->response_latency), 778545Ssaidi@eecs.umich.edu responseLatency(p->response_latency), 788545Ssaidi@eecs.umich.edu numTarget(p->tgts_per_mshr), 798545Ssaidi@eecs.umich.edu forwardSnoops(true), 8010417Sandreas.hansson@arm.com isReadOnly(p->is_read_only), 8110417Sandreas.hansson@arm.com blocked(0), 828545Ssaidi@eecs.umich.edu order(0), 838545Ssaidi@eecs.umich.edu noTargetMSHR(nullptr), 845004Sgblack@eecs.umich.edu missCount(p->max_miss_count), 854183Sgblack@eecs.umich.edu addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()), 864183Sgblack@eecs.umich.edu system(p->system) 874183Sgblack@eecs.umich.edu{ 884183Sgblack@eecs.umich.edu // the MSHR queue has no reserve entries as we check the MSHR 895004Sgblack@eecs.umich.edu // queue on every single allocation, whereas the write queue has 905004Sgblack@eecs.umich.edu // as many reserve entries as we have MSHRs, since every MSHR may 9110417Sandreas.hansson@arm.com // eventually require a writeback, and we do not check the write 9210417Sandreas.hansson@arm.com // buffer before committing to an MSHR 935004Sgblack@eecs.umich.edu 945004Sgblack@eecs.umich.edu // forward snoops is overridden in init() once we can query 955004Sgblack@eecs.umich.edu // whether the connected master is actually snooping or not 965004Sgblack@eecs.umich.edu} 975004Sgblack@eecs.umich.edu 985004Sgblack@eecs.umich.eduvoid 995004Sgblack@eecs.umich.eduBaseCache::CacheSlavePort::setBlocked() 1005004Sgblack@eecs.umich.edu{ 1015004Sgblack@eecs.umich.edu assert(!blocked); 10210417Sandreas.hansson@arm.com DPRINTF(CachePort, "Port is blocking new requests\n"); 10310417Sandreas.hansson@arm.com blocked = true; 1044183Sgblack@eecs.umich.edu // if we already scheduled a retry in this cycle, but it has not yet 1054183Sgblack@eecs.umich.edu // happened, cancel it 1062SN/A if (sendRetryEvent.scheduled()) { 107 owner.deschedule(sendRetryEvent); 108 DPRINTF(CachePort, "Port descheduled retry\n"); 109 mustSendRetry = true; 110 } 111} 112 113void 114BaseCache::CacheSlavePort::clearBlocked() 115{ 116 assert(blocked); 117 DPRINTF(CachePort, "Port is accepting new requests\n"); 118 blocked = false; 119 if (mustSendRetry) { 120 // @TODO: need to find a better time (next cycle?) 121 owner.schedule(sendRetryEvent, curTick() + 1); 122 } 123} 124 125void 126BaseCache::CacheSlavePort::processSendRetry() 127{ 128 DPRINTF(CachePort, "Port is sending retry\n"); 129 130 // reset the flag and call retry 131 mustSendRetry = false; 132 sendRetryReq(); 133} 134 135void 136BaseCache::init() 137{ 138 if (!cpuSidePort->isConnected() || !memSidePort->isConnected()) 139 fatal("Cache ports on %s are not connected\n", name()); 140 cpuSidePort->sendRangeChange(); 141 forwardSnoops = cpuSidePort->isSnooping(); 142} 143 144BaseMasterPort & 145BaseCache::getMasterPort(const std::string &if_name, PortID idx) 146{ 147 if (if_name == "mem_side") { 148 return *memSidePort; 149 } else { 150 return MemObject::getMasterPort(if_name, idx); 151 } 152} 153 154BaseSlavePort & 155BaseCache::getSlavePort(const std::string &if_name, PortID idx) 156{ 157 if (if_name == "cpu_side") { 158 return *cpuSidePort; 159 } else { 160 return MemObject::getSlavePort(if_name, idx); 161 } 162} 163 164bool 165BaseCache::inRange(Addr addr) const 166{ 167 for (const auto& r : addrRanges) { 168 if (r.contains(addr)) { 169 return true; 170 } 171 } 172 return false; 173} 174 175void 176BaseCache::regStats() 177{ 178 using namespace Stats; 179 180 // Hit statistics 181 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 182 MemCmd cmd(access_idx); 183 const string &cstr = cmd.toString(); 184 185 hits[access_idx] 186 .init(system->maxMasters()) 187 .name(name() + "." + cstr + "_hits") 188 .desc("number of " + cstr + " hits") 189 .flags(total | nozero | nonan) 190 ; 191 for (int i = 0; i < system->maxMasters(); i++) { 192 hits[access_idx].subname(i, system->getMasterName(i)); 193 } 194 } 195 196// These macros make it easier to sum the right subset of commands and 197// to change the subset of commands that are considered "demand" vs 198// "non-demand" 199#define SUM_DEMAND(s) \ 200 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::WriteLineReq] + \ 201 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq]) 202 203// should writebacks be included here? prior code was inconsistent... 204#define SUM_NON_DEMAND(s) \ 205 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 206 207 demandHits 208 .name(name() + ".demand_hits") 209 .desc("number of demand (read+write) hits") 210 .flags(total | nozero | nonan) 211 ; 212 demandHits = SUM_DEMAND(hits); 213 for (int i = 0; i < system->maxMasters(); i++) { 214 demandHits.subname(i, system->getMasterName(i)); 215 } 216 217 overallHits 218 .name(name() + ".overall_hits") 219 .desc("number of overall hits") 220 .flags(total | nozero | nonan) 221 ; 222 overallHits = demandHits + SUM_NON_DEMAND(hits); 223 for (int i = 0; i < system->maxMasters(); i++) { 224 overallHits.subname(i, system->getMasterName(i)); 225 } 226 227 // Miss statistics 228 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 229 MemCmd cmd(access_idx); 230 const string &cstr = cmd.toString(); 231 232 misses[access_idx] 233 .init(system->maxMasters()) 234 .name(name() + "." + cstr + "_misses") 235 .desc("number of " + cstr + " misses") 236 .flags(total | nozero | nonan) 237 ; 238 for (int i = 0; i < system->maxMasters(); i++) { 239 misses[access_idx].subname(i, system->getMasterName(i)); 240 } 241 } 242 243 demandMisses 244 .name(name() + ".demand_misses") 245 .desc("number of demand (read+write) misses") 246 .flags(total | nozero | nonan) 247 ; 248 demandMisses = SUM_DEMAND(misses); 249 for (int i = 0; i < system->maxMasters(); i++) { 250 demandMisses.subname(i, system->getMasterName(i)); 251 } 252 253 overallMisses 254 .name(name() + ".overall_misses") 255 .desc("number of overall misses") 256 .flags(total | nozero | nonan) 257 ; 258 overallMisses = demandMisses + SUM_NON_DEMAND(misses); 259 for (int i = 0; i < system->maxMasters(); i++) { 260 overallMisses.subname(i, system->getMasterName(i)); 261 } 262 263 // Miss latency statistics 264 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 265 MemCmd cmd(access_idx); 266 const string &cstr = cmd.toString(); 267 268 missLatency[access_idx] 269 .init(system->maxMasters()) 270 .name(name() + "." + cstr + "_miss_latency") 271 .desc("number of " + cstr + " miss cycles") 272 .flags(total | nozero | nonan) 273 ; 274 for (int i = 0; i < system->maxMasters(); i++) { 275 missLatency[access_idx].subname(i, system->getMasterName(i)); 276 } 277 } 278 279 demandMissLatency 280 .name(name() + ".demand_miss_latency") 281 .desc("number of demand (read+write) miss cycles") 282 .flags(total | nozero | nonan) 283 ; 284 demandMissLatency = SUM_DEMAND(missLatency); 285 for (int i = 0; i < system->maxMasters(); i++) { 286 demandMissLatency.subname(i, system->getMasterName(i)); 287 } 288 289 overallMissLatency 290 .name(name() + ".overall_miss_latency") 291 .desc("number of overall miss cycles") 292 .flags(total | nozero | nonan) 293 ; 294 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 295 for (int i = 0; i < system->maxMasters(); i++) { 296 overallMissLatency.subname(i, system->getMasterName(i)); 297 } 298 299 // access formulas 300 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 301 MemCmd cmd(access_idx); 302 const string &cstr = cmd.toString(); 303 304 accesses[access_idx] 305 .name(name() + "." + cstr + "_accesses") 306 .desc("number of " + cstr + " accesses(hits+misses)") 307 .flags(total | nozero | nonan) 308 ; 309 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 310 311 for (int i = 0; i < system->maxMasters(); i++) { 312 accesses[access_idx].subname(i, system->getMasterName(i)); 313 } 314 } 315 316 demandAccesses 317 .name(name() + ".demand_accesses") 318 .desc("number of demand (read+write) accesses") 319 .flags(total | nozero | nonan) 320 ; 321 demandAccesses = demandHits + demandMisses; 322 for (int i = 0; i < system->maxMasters(); i++) { 323 demandAccesses.subname(i, system->getMasterName(i)); 324 } 325 326 overallAccesses 327 .name(name() + ".overall_accesses") 328 .desc("number of overall (read+write) accesses") 329 .flags(total | nozero | nonan) 330 ; 331 overallAccesses = overallHits + overallMisses; 332 for (int i = 0; i < system->maxMasters(); i++) { 333 overallAccesses.subname(i, system->getMasterName(i)); 334 } 335 336 // miss rate formulas 337 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 338 MemCmd cmd(access_idx); 339 const string &cstr = cmd.toString(); 340 341 missRate[access_idx] 342 .name(name() + "." + cstr + "_miss_rate") 343 .desc("miss rate for " + cstr + " accesses") 344 .flags(total | nozero | nonan) 345 ; 346 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 347 348 for (int i = 0; i < system->maxMasters(); i++) { 349 missRate[access_idx].subname(i, system->getMasterName(i)); 350 } 351 } 352 353 demandMissRate 354 .name(name() + ".demand_miss_rate") 355 .desc("miss rate for demand accesses") 356 .flags(total | nozero | nonan) 357 ; 358 demandMissRate = demandMisses / demandAccesses; 359 for (int i = 0; i < system->maxMasters(); i++) { 360 demandMissRate.subname(i, system->getMasterName(i)); 361 } 362 363 overallMissRate 364 .name(name() + ".overall_miss_rate") 365 .desc("miss rate for overall accesses") 366 .flags(total | nozero | nonan) 367 ; 368 overallMissRate = overallMisses / overallAccesses; 369 for (int i = 0; i < system->maxMasters(); i++) { 370 overallMissRate.subname(i, system->getMasterName(i)); 371 } 372 373 // miss latency formulas 374 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 375 MemCmd cmd(access_idx); 376 const string &cstr = cmd.toString(); 377 378 avgMissLatency[access_idx] 379 .name(name() + "." + cstr + "_avg_miss_latency") 380 .desc("average " + cstr + " miss latency") 381 .flags(total | nozero | nonan) 382 ; 383 avgMissLatency[access_idx] = 384 missLatency[access_idx] / misses[access_idx]; 385 386 for (int i = 0; i < system->maxMasters(); i++) { 387 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 388 } 389 } 390 391 demandAvgMissLatency 392 .name(name() + ".demand_avg_miss_latency") 393 .desc("average overall miss latency") 394 .flags(total | nozero | nonan) 395 ; 396 demandAvgMissLatency = demandMissLatency / demandMisses; 397 for (int i = 0; i < system->maxMasters(); i++) { 398 demandAvgMissLatency.subname(i, system->getMasterName(i)); 399 } 400 401 overallAvgMissLatency 402 .name(name() + ".overall_avg_miss_latency") 403 .desc("average overall miss latency") 404 .flags(total | nozero | nonan) 405 ; 406 overallAvgMissLatency = overallMissLatency / overallMisses; 407 for (int i = 0; i < system->maxMasters(); i++) { 408 overallAvgMissLatency.subname(i, system->getMasterName(i)); 409 } 410 411 blocked_cycles.init(NUM_BLOCKED_CAUSES); 412 blocked_cycles 413 .name(name() + ".blocked_cycles") 414 .desc("number of cycles access was blocked") 415 .subname(Blocked_NoMSHRs, "no_mshrs") 416 .subname(Blocked_NoTargets, "no_targets") 417 ; 418 419 420 blocked_causes.init(NUM_BLOCKED_CAUSES); 421 blocked_causes 422 .name(name() + ".blocked") 423 .desc("number of cycles access was blocked") 424 .subname(Blocked_NoMSHRs, "no_mshrs") 425 .subname(Blocked_NoTargets, "no_targets") 426 ; 427 428 avg_blocked 429 .name(name() + ".avg_blocked_cycles") 430 .desc("average number of cycles each access was blocked") 431 .subname(Blocked_NoMSHRs, "no_mshrs") 432 .subname(Blocked_NoTargets, "no_targets") 433 ; 434 435 avg_blocked = blocked_cycles / blocked_causes; 436 437 unusedPrefetches 438 .name(name() + ".unused_prefetches") 439 .desc("number of HardPF blocks evicted w/o reference") 440 .flags(nozero) 441 ; 442 443 writebacks 444 .init(system->maxMasters()) 445 .name(name() + ".writebacks") 446 .desc("number of writebacks") 447 .flags(total | nozero | nonan) 448 ; 449 for (int i = 0; i < system->maxMasters(); i++) { 450 writebacks.subname(i, system->getMasterName(i)); 451 } 452 453 // MSHR statistics 454 // MSHR hit 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_hits[access_idx] 460 .init(system->maxMasters()) 461 .name(name() + "." + cstr + "_mshr_hits") 462 .desc("number of " + cstr + " MSHR hits") 463 .flags(total | nozero | nonan) 464 ; 465 for (int i = 0; i < system->maxMasters(); i++) { 466 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 467 } 468 } 469 470 demandMshrHits 471 .name(name() + ".demand_mshr_hits") 472 .desc("number of demand (read+write) MSHR hits") 473 .flags(total | nozero | nonan) 474 ; 475 demandMshrHits = SUM_DEMAND(mshr_hits); 476 for (int i = 0; i < system->maxMasters(); i++) { 477 demandMshrHits.subname(i, system->getMasterName(i)); 478 } 479 480 overallMshrHits 481 .name(name() + ".overall_mshr_hits") 482 .desc("number of overall MSHR hits") 483 .flags(total | nozero | nonan) 484 ; 485 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 486 for (int i = 0; i < system->maxMasters(); i++) { 487 overallMshrHits.subname(i, system->getMasterName(i)); 488 } 489 490 // MSHR miss 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_misses[access_idx] 496 .init(system->maxMasters()) 497 .name(name() + "." + cstr + "_mshr_misses") 498 .desc("number of " + cstr + " MSHR misses") 499 .flags(total | nozero | nonan) 500 ; 501 for (int i = 0; i < system->maxMasters(); i++) { 502 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 503 } 504 } 505 506 demandMshrMisses 507 .name(name() + ".demand_mshr_misses") 508 .desc("number of demand (read+write) MSHR misses") 509 .flags(total | nozero | nonan) 510 ; 511 demandMshrMisses = SUM_DEMAND(mshr_misses); 512 for (int i = 0; i < system->maxMasters(); i++) { 513 demandMshrMisses.subname(i, system->getMasterName(i)); 514 } 515 516 overallMshrMisses 517 .name(name() + ".overall_mshr_misses") 518 .desc("number of overall MSHR misses") 519 .flags(total | nozero | nonan) 520 ; 521 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 522 for (int i = 0; i < system->maxMasters(); i++) { 523 overallMshrMisses.subname(i, system->getMasterName(i)); 524 } 525 526 // MSHR miss latency statistics 527 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 528 MemCmd cmd(access_idx); 529 const string &cstr = cmd.toString(); 530 531 mshr_miss_latency[access_idx] 532 .init(system->maxMasters()) 533 .name(name() + "." + cstr + "_mshr_miss_latency") 534 .desc("number of " + cstr + " MSHR miss cycles") 535 .flags(total | nozero | nonan) 536 ; 537 for (int i = 0; i < system->maxMasters(); i++) { 538 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 539 } 540 } 541 542 demandMshrMissLatency 543 .name(name() + ".demand_mshr_miss_latency") 544 .desc("number of demand (read+write) MSHR miss cycles") 545 .flags(total | nozero | nonan) 546 ; 547 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 548 for (int i = 0; i < system->maxMasters(); i++) { 549 demandMshrMissLatency.subname(i, system->getMasterName(i)); 550 } 551 552 overallMshrMissLatency 553 .name(name() + ".overall_mshr_miss_latency") 554 .desc("number of overall MSHR miss cycles") 555 .flags(total | nozero | nonan) 556 ; 557 overallMshrMissLatency = 558 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 559 for (int i = 0; i < system->maxMasters(); i++) { 560 overallMshrMissLatency.subname(i, system->getMasterName(i)); 561 } 562 563 // MSHR uncacheable statistics 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 mshr_uncacheable[access_idx] 569 .init(system->maxMasters()) 570 .name(name() + "." + cstr + "_mshr_uncacheable") 571 .desc("number of " + cstr + " MSHR uncacheable") 572 .flags(total | nozero | nonan) 573 ; 574 for (int i = 0; i < system->maxMasters(); i++) { 575 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 576 } 577 } 578 579 overallMshrUncacheable 580 .name(name() + ".overall_mshr_uncacheable_misses") 581 .desc("number of overall MSHR uncacheable misses") 582 .flags(total | nozero | nonan) 583 ; 584 overallMshrUncacheable = 585 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 586 for (int i = 0; i < system->maxMasters(); i++) { 587 overallMshrUncacheable.subname(i, system->getMasterName(i)); 588 } 589 590 // MSHR miss latency statistics 591 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 592 MemCmd cmd(access_idx); 593 const string &cstr = cmd.toString(); 594 595 mshr_uncacheable_lat[access_idx] 596 .init(system->maxMasters()) 597 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 598 .desc("number of " + cstr + " MSHR uncacheable cycles") 599 .flags(total | nozero | nonan) 600 ; 601 for (int i = 0; i < system->maxMasters(); i++) { 602 mshr_uncacheable_lat[access_idx].subname( 603 i, system->getMasterName(i)); 604 } 605 } 606 607 overallMshrUncacheableLatency 608 .name(name() + ".overall_mshr_uncacheable_latency") 609 .desc("number of overall MSHR uncacheable cycles") 610 .flags(total | nozero | nonan) 611 ; 612 overallMshrUncacheableLatency = 613 SUM_DEMAND(mshr_uncacheable_lat) + 614 SUM_NON_DEMAND(mshr_uncacheable_lat); 615 for (int i = 0; i < system->maxMasters(); i++) { 616 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 617 } 618 619#if 0 620 // MSHR access formulas 621 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 622 MemCmd cmd(access_idx); 623 const string &cstr = cmd.toString(); 624 625 mshrAccesses[access_idx] 626 .name(name() + "." + cstr + "_mshr_accesses") 627 .desc("number of " + cstr + " mshr accesses(hits+misses)") 628 .flags(total | nozero | nonan) 629 ; 630 mshrAccesses[access_idx] = 631 mshr_hits[access_idx] + mshr_misses[access_idx] 632 + mshr_uncacheable[access_idx]; 633 } 634 635 demandMshrAccesses 636 .name(name() + ".demand_mshr_accesses") 637 .desc("number of demand (read+write) mshr accesses") 638 .flags(total | nozero | nonan) 639 ; 640 demandMshrAccesses = demandMshrHits + demandMshrMisses; 641 642 overallMshrAccesses 643 .name(name() + ".overall_mshr_accesses") 644 .desc("number of overall (read+write) mshr accesses") 645 .flags(total | nozero | nonan) 646 ; 647 overallMshrAccesses = overallMshrHits + overallMshrMisses 648 + overallMshrUncacheable; 649#endif 650 651 // MSHR miss rate formulas 652 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 653 MemCmd cmd(access_idx); 654 const string &cstr = cmd.toString(); 655 656 mshrMissRate[access_idx] 657 .name(name() + "." + cstr + "_mshr_miss_rate") 658 .desc("mshr miss rate for " + cstr + " accesses") 659 .flags(total | nozero | nonan) 660 ; 661 mshrMissRate[access_idx] = 662 mshr_misses[access_idx] / accesses[access_idx]; 663 664 for (int i = 0; i < system->maxMasters(); i++) { 665 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 666 } 667 } 668 669 demandMshrMissRate 670 .name(name() + ".demand_mshr_miss_rate") 671 .desc("mshr miss rate for demand accesses") 672 .flags(total | nozero | nonan) 673 ; 674 demandMshrMissRate = demandMshrMisses / demandAccesses; 675 for (int i = 0; i < system->maxMasters(); i++) { 676 demandMshrMissRate.subname(i, system->getMasterName(i)); 677 } 678 679 overallMshrMissRate 680 .name(name() + ".overall_mshr_miss_rate") 681 .desc("mshr miss rate for overall accesses") 682 .flags(total | nozero | nonan) 683 ; 684 overallMshrMissRate = overallMshrMisses / overallAccesses; 685 for (int i = 0; i < system->maxMasters(); i++) { 686 overallMshrMissRate.subname(i, system->getMasterName(i)); 687 } 688 689 // mshrMiss latency formulas 690 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 691 MemCmd cmd(access_idx); 692 const string &cstr = cmd.toString(); 693 694 avgMshrMissLatency[access_idx] 695 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 696 .desc("average " + cstr + " mshr miss latency") 697 .flags(total | nozero | nonan) 698 ; 699 avgMshrMissLatency[access_idx] = 700 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 701 702 for (int i = 0; i < system->maxMasters(); i++) { 703 avgMshrMissLatency[access_idx].subname( 704 i, system->getMasterName(i)); 705 } 706 } 707 708 demandAvgMshrMissLatency 709 .name(name() + ".demand_avg_mshr_miss_latency") 710 .desc("average overall mshr miss latency") 711 .flags(total | nozero | nonan) 712 ; 713 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 714 for (int i = 0; i < system->maxMasters(); i++) { 715 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 716 } 717 718 overallAvgMshrMissLatency 719 .name(name() + ".overall_avg_mshr_miss_latency") 720 .desc("average overall mshr miss latency") 721 .flags(total | nozero | nonan) 722 ; 723 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 724 for (int i = 0; i < system->maxMasters(); i++) { 725 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 726 } 727 728 // mshrUncacheable latency formulas 729 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 730 MemCmd cmd(access_idx); 731 const string &cstr = cmd.toString(); 732 733 avgMshrUncacheableLatency[access_idx] 734 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 735 .desc("average " + cstr + " mshr uncacheable latency") 736 .flags(total | nozero | nonan) 737 ; 738 avgMshrUncacheableLatency[access_idx] = 739 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 740 741 for (int i = 0; i < system->maxMasters(); i++) { 742 avgMshrUncacheableLatency[access_idx].subname( 743 i, system->getMasterName(i)); 744 } 745 } 746 747 overallAvgMshrUncacheableLatency 748 .name(name() + ".overall_avg_mshr_uncacheable_latency") 749 .desc("average overall mshr uncacheable latency") 750 .flags(total | nozero | nonan) 751 ; 752 overallAvgMshrUncacheableLatency = 753 overallMshrUncacheableLatency / overallMshrUncacheable; 754 for (int i = 0; i < system->maxMasters(); i++) { 755 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 756 } 757 758} 759