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