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"
| 1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2003-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Erik Hallnor 41 */ 42 43/** 44 * @file 45 * Definition of BaseCache functions. 46 */ 47 48#include "cpu/base.hh" 49#include "cpu/smt.hh" 50#include "debug/Cache.hh"
|
51#include "mem/cache/base.hh" 52#include "mem/cache/mshr.hh" 53#include "sim/full_system.hh" 54 55using namespace std; 56 57BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name, 58 BaseCache *_cache, 59 const std::string &_label) 60 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label), 61 blocked(false), mustSendRetry(false), sendRetryEvent(this) 62{ 63} 64 65BaseCache::BaseCache(const Params *p) 66 : MemObject(p), 67 mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs), 68 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 69 MSHRQueue_WriteBuffer), 70 blkSize(p->block_size), 71 hitLatency(p->latency), 72 numTarget(p->tgts_per_mshr), 73 forwardSnoops(p->forward_snoops), 74 isTopLevel(p->is_top_level), 75 blocked(0), 76 noTargetMSHR(NULL), 77 missCount(p->max_miss_count), 78 drainEvent(NULL), 79 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()), 80 system(p->system) 81{ 82} 83 84void 85BaseCache::CacheSlavePort::setBlocked() 86{ 87 assert(!blocked); 88 DPRINTF(CachePort, "Cache port %s blocking new requests\n", name()); 89 blocked = true; 90} 91 92void 93BaseCache::CacheSlavePort::clearBlocked() 94{ 95 assert(blocked); 96 DPRINTF(CachePort, "Cache port %s accepting new requests\n", name()); 97 blocked = false; 98 if (mustSendRetry) { 99 DPRINTF(CachePort, "Cache port %s sending retry\n", name()); 100 mustSendRetry = false; 101 // @TODO: need to find a better time (next bus cycle?) 102 owner.schedule(sendRetryEvent, curTick() + 1); 103 } 104} 105 106 107void 108BaseCache::init() 109{ 110 if (!cpuSidePort->isConnected() || !memSidePort->isConnected()) 111 fatal("Cache ports on %s are not connected\n", name()); 112 cpuSidePort->sendRangeChange(); 113} 114 115MasterPort & 116BaseCache::getMasterPort(const std::string &if_name, int idx) 117{ 118 if (if_name == "mem_side") { 119 return *memSidePort; 120 } else { 121 return MemObject::getMasterPort(if_name, idx); 122 } 123} 124 125SlavePort & 126BaseCache::getSlavePort(const std::string &if_name, int idx) 127{ 128 if (if_name == "cpu_side") { 129 return *cpuSidePort; 130 } else { 131 return MemObject::getSlavePort(if_name, idx); 132 } 133} 134 135void 136BaseCache::regStats() 137{ 138 using namespace Stats; 139 140 // Hit statistics 141 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 142 MemCmd cmd(access_idx); 143 const string &cstr = cmd.toString(); 144 145 hits[access_idx] 146 .init(system->maxMasters()) 147 .name(name() + "." + cstr + "_hits") 148 .desc("number of " + cstr + " hits") 149 .flags(total | nozero | nonan) 150 ; 151 for (int i = 0; i < system->maxMasters(); i++) { 152 hits[access_idx].subname(i, system->getMasterName(i)); 153 } 154 } 155 156// These macros make it easier to sum the right subset of commands and 157// to change the subset of commands that are considered "demand" vs 158// "non-demand" 159#define SUM_DEMAND(s) \ 160 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq]) 161 162// should writebacks be included here? prior code was inconsistent... 163#define SUM_NON_DEMAND(s) \ 164 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 165 166 demandHits 167 .name(name() + ".demand_hits") 168 .desc("number of demand (read+write) hits") 169 .flags(total | nozero | nonan) 170 ; 171 demandHits = SUM_DEMAND(hits); 172 for (int i = 0; i < system->maxMasters(); i++) { 173 demandHits.subname(i, system->getMasterName(i)); 174 } 175 176 overallHits 177 .name(name() + ".overall_hits") 178 .desc("number of overall hits") 179 .flags(total | nozero | nonan) 180 ; 181 overallHits = demandHits + SUM_NON_DEMAND(hits); 182 for (int i = 0; i < system->maxMasters(); i++) { 183 overallHits.subname(i, system->getMasterName(i)); 184 } 185 186 // Miss statistics 187 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 188 MemCmd cmd(access_idx); 189 const string &cstr = cmd.toString(); 190 191 misses[access_idx] 192 .init(system->maxMasters()) 193 .name(name() + "." + cstr + "_misses") 194 .desc("number of " + cstr + " misses") 195 .flags(total | nozero | nonan) 196 ; 197 for (int i = 0; i < system->maxMasters(); i++) { 198 misses[access_idx].subname(i, system->getMasterName(i)); 199 } 200 } 201 202 demandMisses 203 .name(name() + ".demand_misses") 204 .desc("number of demand (read+write) misses") 205 .flags(total | nozero | nonan) 206 ; 207 demandMisses = SUM_DEMAND(misses); 208 for (int i = 0; i < system->maxMasters(); i++) { 209 demandMisses.subname(i, system->getMasterName(i)); 210 } 211 212 overallMisses 213 .name(name() + ".overall_misses") 214 .desc("number of overall misses") 215 .flags(total | nozero | nonan) 216 ; 217 overallMisses = demandMisses + SUM_NON_DEMAND(misses); 218 for (int i = 0; i < system->maxMasters(); i++) { 219 overallMisses.subname(i, system->getMasterName(i)); 220 } 221 222 // Miss latency statistics 223 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 224 MemCmd cmd(access_idx); 225 const string &cstr = cmd.toString(); 226 227 missLatency[access_idx] 228 .init(system->maxMasters()) 229 .name(name() + "." + cstr + "_miss_latency") 230 .desc("number of " + cstr + " miss cycles") 231 .flags(total | nozero | nonan) 232 ; 233 for (int i = 0; i < system->maxMasters(); i++) { 234 missLatency[access_idx].subname(i, system->getMasterName(i)); 235 } 236 } 237 238 demandMissLatency 239 .name(name() + ".demand_miss_latency") 240 .desc("number of demand (read+write) miss cycles") 241 .flags(total | nozero | nonan) 242 ; 243 demandMissLatency = SUM_DEMAND(missLatency); 244 for (int i = 0; i < system->maxMasters(); i++) { 245 demandMissLatency.subname(i, system->getMasterName(i)); 246 } 247 248 overallMissLatency 249 .name(name() + ".overall_miss_latency") 250 .desc("number of overall miss cycles") 251 .flags(total | nozero | nonan) 252 ; 253 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 254 for (int i = 0; i < system->maxMasters(); i++) { 255 overallMissLatency.subname(i, system->getMasterName(i)); 256 } 257 258 // access formulas 259 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 260 MemCmd cmd(access_idx); 261 const string &cstr = cmd.toString(); 262 263 accesses[access_idx] 264 .name(name() + "." + cstr + "_accesses") 265 .desc("number of " + cstr + " accesses(hits+misses)") 266 .flags(total | nozero | nonan) 267 ; 268 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 269 270 for (int i = 0; i < system->maxMasters(); i++) { 271 accesses[access_idx].subname(i, system->getMasterName(i)); 272 } 273 } 274 275 demandAccesses 276 .name(name() + ".demand_accesses") 277 .desc("number of demand (read+write) accesses") 278 .flags(total | nozero | nonan) 279 ; 280 demandAccesses = demandHits + demandMisses; 281 for (int i = 0; i < system->maxMasters(); i++) { 282 demandAccesses.subname(i, system->getMasterName(i)); 283 } 284 285 overallAccesses 286 .name(name() + ".overall_accesses") 287 .desc("number of overall (read+write) accesses") 288 .flags(total | nozero | nonan) 289 ; 290 overallAccesses = overallHits + overallMisses; 291 for (int i = 0; i < system->maxMasters(); i++) { 292 overallAccesses.subname(i, system->getMasterName(i)); 293 } 294 295 // miss rate formulas 296 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 297 MemCmd cmd(access_idx); 298 const string &cstr = cmd.toString(); 299 300 missRate[access_idx] 301 .name(name() + "." + cstr + "_miss_rate") 302 .desc("miss rate for " + cstr + " accesses") 303 .flags(total | nozero | nonan) 304 ; 305 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 306 307 for (int i = 0; i < system->maxMasters(); i++) { 308 missRate[access_idx].subname(i, system->getMasterName(i)); 309 } 310 } 311 312 demandMissRate 313 .name(name() + ".demand_miss_rate") 314 .desc("miss rate for demand accesses") 315 .flags(total | nozero | nonan) 316 ; 317 demandMissRate = demandMisses / demandAccesses; 318 for (int i = 0; i < system->maxMasters(); i++) { 319 demandMissRate.subname(i, system->getMasterName(i)); 320 } 321 322 overallMissRate 323 .name(name() + ".overall_miss_rate") 324 .desc("miss rate for overall accesses") 325 .flags(total | nozero | nonan) 326 ; 327 overallMissRate = overallMisses / overallAccesses; 328 for (int i = 0; i < system->maxMasters(); i++) { 329 overallMissRate.subname(i, system->getMasterName(i)); 330 } 331 332 // miss latency formulas 333 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 334 MemCmd cmd(access_idx); 335 const string &cstr = cmd.toString(); 336 337 avgMissLatency[access_idx] 338 .name(name() + "." + cstr + "_avg_miss_latency") 339 .desc("average " + cstr + " miss latency") 340 .flags(total | nozero | nonan) 341 ; 342 avgMissLatency[access_idx] = 343 missLatency[access_idx] / misses[access_idx]; 344 345 for (int i = 0; i < system->maxMasters(); i++) { 346 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 347 } 348 } 349 350 demandAvgMissLatency 351 .name(name() + ".demand_avg_miss_latency") 352 .desc("average overall miss latency") 353 .flags(total | nozero | nonan) 354 ; 355 demandAvgMissLatency = demandMissLatency / demandMisses; 356 for (int i = 0; i < system->maxMasters(); i++) { 357 demandAvgMissLatency.subname(i, system->getMasterName(i)); 358 } 359 360 overallAvgMissLatency 361 .name(name() + ".overall_avg_miss_latency") 362 .desc("average overall miss latency") 363 .flags(total | nozero | nonan) 364 ; 365 overallAvgMissLatency = overallMissLatency / overallMisses; 366 for (int i = 0; i < system->maxMasters(); i++) { 367 overallAvgMissLatency.subname(i, system->getMasterName(i)); 368 } 369 370 blocked_cycles.init(NUM_BLOCKED_CAUSES); 371 blocked_cycles 372 .name(name() + ".blocked_cycles") 373 .desc("number of cycles access was blocked") 374 .subname(Blocked_NoMSHRs, "no_mshrs") 375 .subname(Blocked_NoTargets, "no_targets") 376 ; 377 378 379 blocked_causes.init(NUM_BLOCKED_CAUSES); 380 blocked_causes 381 .name(name() + ".blocked") 382 .desc("number of cycles access was blocked") 383 .subname(Blocked_NoMSHRs, "no_mshrs") 384 .subname(Blocked_NoTargets, "no_targets") 385 ; 386 387 avg_blocked 388 .name(name() + ".avg_blocked_cycles") 389 .desc("average number of cycles each access was blocked") 390 .subname(Blocked_NoMSHRs, "no_mshrs") 391 .subname(Blocked_NoTargets, "no_targets") 392 ; 393 394 avg_blocked = blocked_cycles / blocked_causes; 395 396 fastWrites 397 .name(name() + ".fast_writes") 398 .desc("number of fast writes performed") 399 ; 400 401 cacheCopies 402 .name(name() + ".cache_copies") 403 .desc("number of cache copies performed") 404 ; 405 406 writebacks 407 .init(system->maxMasters()) 408 .name(name() + ".writebacks") 409 .desc("number of writebacks") 410 .flags(total | nozero | nonan) 411 ; 412 for (int i = 0; i < system->maxMasters(); i++) { 413 writebacks.subname(i, system->getMasterName(i)); 414 } 415 416 // MSHR statistics 417 // MSHR hit statistics 418 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 419 MemCmd cmd(access_idx); 420 const string &cstr = cmd.toString(); 421 422 mshr_hits[access_idx] 423 .init(system->maxMasters()) 424 .name(name() + "." + cstr + "_mshr_hits") 425 .desc("number of " + cstr + " MSHR hits") 426 .flags(total | nozero | nonan) 427 ; 428 for (int i = 0; i < system->maxMasters(); i++) { 429 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 430 } 431 } 432 433 demandMshrHits 434 .name(name() + ".demand_mshr_hits") 435 .desc("number of demand (read+write) MSHR hits") 436 .flags(total | nozero | nonan) 437 ; 438 demandMshrHits = SUM_DEMAND(mshr_hits); 439 for (int i = 0; i < system->maxMasters(); i++) { 440 demandMshrHits.subname(i, system->getMasterName(i)); 441 } 442 443 overallMshrHits 444 .name(name() + ".overall_mshr_hits") 445 .desc("number of overall MSHR hits") 446 .flags(total | nozero | nonan) 447 ; 448 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 449 for (int i = 0; i < system->maxMasters(); i++) { 450 overallMshrHits.subname(i, system->getMasterName(i)); 451 } 452 453 // MSHR miss statistics 454 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 455 MemCmd cmd(access_idx); 456 const string &cstr = cmd.toString(); 457 458 mshr_misses[access_idx] 459 .init(system->maxMasters()) 460 .name(name() + "." + cstr + "_mshr_misses") 461 .desc("number of " + cstr + " MSHR misses") 462 .flags(total | nozero | nonan) 463 ; 464 for (int i = 0; i < system->maxMasters(); i++) { 465 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 466 } 467 } 468 469 demandMshrMisses 470 .name(name() + ".demand_mshr_misses") 471 .desc("number of demand (read+write) MSHR misses") 472 .flags(total | nozero | nonan) 473 ; 474 demandMshrMisses = SUM_DEMAND(mshr_misses); 475 for (int i = 0; i < system->maxMasters(); i++) { 476 demandMshrMisses.subname(i, system->getMasterName(i)); 477 } 478 479 overallMshrMisses 480 .name(name() + ".overall_mshr_misses") 481 .desc("number of overall MSHR misses") 482 .flags(total | nozero | nonan) 483 ; 484 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 485 for (int i = 0; i < system->maxMasters(); i++) { 486 overallMshrMisses.subname(i, system->getMasterName(i)); 487 } 488 489 // MSHR miss latency statistics 490 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 491 MemCmd cmd(access_idx); 492 const string &cstr = cmd.toString(); 493 494 mshr_miss_latency[access_idx] 495 .init(system->maxMasters()) 496 .name(name() + "." + cstr + "_mshr_miss_latency") 497 .desc("number of " + cstr + " MSHR miss cycles") 498 .flags(total | nozero | nonan) 499 ; 500 for (int i = 0; i < system->maxMasters(); i++) { 501 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 502 } 503 } 504 505 demandMshrMissLatency 506 .name(name() + ".demand_mshr_miss_latency") 507 .desc("number of demand (read+write) MSHR miss cycles") 508 .flags(total | nozero | nonan) 509 ; 510 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 511 for (int i = 0; i < system->maxMasters(); i++) { 512 demandMshrMissLatency.subname(i, system->getMasterName(i)); 513 } 514 515 overallMshrMissLatency 516 .name(name() + ".overall_mshr_miss_latency") 517 .desc("number of overall MSHR miss cycles") 518 .flags(total | nozero | nonan) 519 ; 520 overallMshrMissLatency = 521 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 522 for (int i = 0; i < system->maxMasters(); i++) { 523 overallMshrMissLatency.subname(i, system->getMasterName(i)); 524 } 525 526 // MSHR uncacheable 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_uncacheable[access_idx] 532 .init(system->maxMasters()) 533 .name(name() + "." + cstr + "_mshr_uncacheable") 534 .desc("number of " + cstr + " MSHR uncacheable") 535 .flags(total | nozero | nonan) 536 ; 537 for (int i = 0; i < system->maxMasters(); i++) { 538 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 539 } 540 } 541 542 overallMshrUncacheable 543 .name(name() + ".overall_mshr_uncacheable_misses") 544 .desc("number of overall MSHR uncacheable misses") 545 .flags(total | nozero | nonan) 546 ; 547 overallMshrUncacheable = 548 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 549 for (int i = 0; i < system->maxMasters(); i++) { 550 overallMshrUncacheable.subname(i, system->getMasterName(i)); 551 } 552 553 // MSHR miss latency statistics 554 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 555 MemCmd cmd(access_idx); 556 const string &cstr = cmd.toString(); 557 558 mshr_uncacheable_lat[access_idx] 559 .init(system->maxMasters()) 560 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 561 .desc("number of " + cstr + " MSHR uncacheable cycles") 562 .flags(total | nozero | nonan) 563 ; 564 for (int i = 0; i < system->maxMasters(); i++) { 565 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i)); 566 } 567 } 568 569 overallMshrUncacheableLatency 570 .name(name() + ".overall_mshr_uncacheable_latency") 571 .desc("number of overall MSHR uncacheable cycles") 572 .flags(total | nozero | nonan) 573 ; 574 overallMshrUncacheableLatency = 575 SUM_DEMAND(mshr_uncacheable_lat) + 576 SUM_NON_DEMAND(mshr_uncacheable_lat); 577 for (int i = 0; i < system->maxMasters(); i++) { 578 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 579 } 580 581#if 0 582 // MSHR access formulas 583 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 584 MemCmd cmd(access_idx); 585 const string &cstr = cmd.toString(); 586 587 mshrAccesses[access_idx] 588 .name(name() + "." + cstr + "_mshr_accesses") 589 .desc("number of " + cstr + " mshr accesses(hits+misses)") 590 .flags(total | nozero | nonan) 591 ; 592 mshrAccesses[access_idx] = 593 mshr_hits[access_idx] + mshr_misses[access_idx] 594 + mshr_uncacheable[access_idx]; 595 } 596 597 demandMshrAccesses 598 .name(name() + ".demand_mshr_accesses") 599 .desc("number of demand (read+write) mshr accesses") 600 .flags(total | nozero | nonan) 601 ; 602 demandMshrAccesses = demandMshrHits + demandMshrMisses; 603 604 overallMshrAccesses 605 .name(name() + ".overall_mshr_accesses") 606 .desc("number of overall (read+write) mshr accesses") 607 .flags(total | nozero | nonan) 608 ; 609 overallMshrAccesses = overallMshrHits + overallMshrMisses 610 + overallMshrUncacheable; 611#endif 612 613 // MSHR miss rate formulas 614 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 615 MemCmd cmd(access_idx); 616 const string &cstr = cmd.toString(); 617 618 mshrMissRate[access_idx] 619 .name(name() + "." + cstr + "_mshr_miss_rate") 620 .desc("mshr miss rate for " + cstr + " accesses") 621 .flags(total | nozero | nonan) 622 ; 623 mshrMissRate[access_idx] = 624 mshr_misses[access_idx] / accesses[access_idx]; 625 626 for (int i = 0; i < system->maxMasters(); i++) { 627 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 628 } 629 } 630 631 demandMshrMissRate 632 .name(name() + ".demand_mshr_miss_rate") 633 .desc("mshr miss rate for demand accesses") 634 .flags(total | nozero | nonan) 635 ; 636 demandMshrMissRate = demandMshrMisses / demandAccesses; 637 for (int i = 0; i < system->maxMasters(); i++) { 638 demandMshrMissRate.subname(i, system->getMasterName(i)); 639 } 640 641 overallMshrMissRate 642 .name(name() + ".overall_mshr_miss_rate") 643 .desc("mshr miss rate for overall accesses") 644 .flags(total | nozero | nonan) 645 ; 646 overallMshrMissRate = overallMshrMisses / overallAccesses; 647 for (int i = 0; i < system->maxMasters(); i++) { 648 overallMshrMissRate.subname(i, system->getMasterName(i)); 649 } 650 651 // mshrMiss latency 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 avgMshrMissLatency[access_idx] 657 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 658 .desc("average " + cstr + " mshr miss latency") 659 .flags(total | nozero | nonan) 660 ; 661 avgMshrMissLatency[access_idx] = 662 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 663 664 for (int i = 0; i < system->maxMasters(); i++) { 665 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i)); 666 } 667 } 668 669 demandAvgMshrMissLatency 670 .name(name() + ".demand_avg_mshr_miss_latency") 671 .desc("average overall mshr miss latency") 672 .flags(total | nozero | nonan) 673 ; 674 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 675 for (int i = 0; i < system->maxMasters(); i++) { 676 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 677 } 678 679 overallAvgMshrMissLatency 680 .name(name() + ".overall_avg_mshr_miss_latency") 681 .desc("average overall mshr miss latency") 682 .flags(total | nozero | nonan) 683 ; 684 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 685 for (int i = 0; i < system->maxMasters(); i++) { 686 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 687 } 688 689 // mshrUncacheable 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 avgMshrUncacheableLatency[access_idx] 695 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 696 .desc("average " + cstr + " mshr uncacheable latency") 697 .flags(total | nozero | nonan) 698 ; 699 avgMshrUncacheableLatency[access_idx] = 700 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 701 702 for (int i = 0; i < system->maxMasters(); i++) { 703 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i)); 704 } 705 } 706 707 overallAvgMshrUncacheableLatency 708 .name(name() + ".overall_avg_mshr_uncacheable_latency") 709 .desc("average overall mshr uncacheable latency") 710 .flags(total | nozero | nonan) 711 ; 712 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 713 for (int i = 0; i < system->maxMasters(); i++) { 714 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 715 } 716 717 mshr_cap_events 718 .init(system->maxMasters()) 719 .name(name() + ".mshr_cap_events") 720 .desc("number of times MSHR cap was activated") 721 .flags(total | nozero | nonan) 722 ; 723 for (int i = 0; i < system->maxMasters(); i++) { 724 mshr_cap_events.subname(i, system->getMasterName(i)); 725 } 726 727 //software prefetching stats 728 soft_prefetch_mshr_full 729 .init(system->maxMasters()) 730 .name(name() + ".soft_prefetch_mshr_full") 731 .desc("number of mshr full events for SW prefetching instrutions") 732 .flags(total | nozero | nonan) 733 ; 734 for (int i = 0; i < system->maxMasters(); i++) { 735 soft_prefetch_mshr_full.subname(i, system->getMasterName(i)); 736 } 737 738 mshr_no_allocate_misses 739 .name(name() +".no_allocate_misses") 740 .desc("Number of misses that were no-allocate") 741 ; 742 743} 744 745unsigned int 746BaseCache::drain(Event *de) 747{ 748 int count = memSidePort->drain(de) + cpuSidePort->drain(de); 749 750 // Set status 751 if (count != 0) { 752 drainEvent = de; 753 754 changeState(SimObject::Draining);
| 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->latency), 73 numTarget(p->tgts_per_mshr), 74 forwardSnoops(p->forward_snoops), 75 isTopLevel(p->is_top_level), 76 blocked(0), 77 noTargetMSHR(NULL), 78 missCount(p->max_miss_count), 79 drainEvent(NULL), 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 116MasterPort & 117BaseCache::getMasterPort(const std::string &if_name, int idx) 118{ 119 if (if_name == "mem_side") { 120 return *memSidePort; 121 } else { 122 return MemObject::getMasterPort(if_name, idx); 123 } 124} 125 126SlavePort & 127BaseCache::getSlavePort(const std::string &if_name, int 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(Event *de) 748{ 749 int count = memSidePort->drain(de) + cpuSidePort->drain(de); 750 751 // Set status 752 if (count != 0) { 753 drainEvent = de; 754 755 changeState(SimObject::Draining);
|