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