base.cc revision 4628
12686Sksewell@umich.edu/* 22686Sksewell@umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 32686Sksewell@umich.edu * All rights reserved. 42686Sksewell@umich.edu * 52686Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 62686Sksewell@umich.edu * modification, are permitted provided that the following conditions are 72686Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 82686Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 92686Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 102686Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 112686Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 122686Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 132686Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 142686Sksewell@umich.edu * this software without specific prior written permission. 152686Sksewell@umich.edu * 162686Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172686Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182686Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192686Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202686Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212686Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222686Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232686Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242686Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252686Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262686Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272706Sksewell@umich.edu * 282706Sksewell@umich.edu * Authors: Erik Hallnor 292686Sksewell@umich.edu */ 302686Sksewell@umich.edu 314661Sksewell@umich.edu/** 322686Sksewell@umich.edu * @file 334661Sksewell@umich.edu * Definition of BaseCache functions. 344661Sksewell@umich.edu */ 354661Sksewell@umich.edu 364661Sksewell@umich.edu#include "cpu/base.hh" 374661Sksewell@umich.edu#include "cpu/smt.hh" 384661Sksewell@umich.edu#include "mem/cache/base_cache.hh" 392980Sgblack@eecs.umich.edu#include "mem/cache/miss/mshr.hh" 402686Sksewell@umich.edu 412686Sksewell@umich.eduusing namespace std; 424661Sksewell@umich.edu 432686Sksewell@umich.eduBaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache) 442686Sksewell@umich.edu : SimpleTimingPort(_name, _cache), cache(_cache), otherPort(NULL), 452686Sksewell@umich.edu blocked(false), waitingOnRetry(false), mustSendRetry(false), 462686Sksewell@umich.edu requestCauses(0) 472686Sksewell@umich.edu{ 482686Sksewell@umich.edu} 492686Sksewell@umich.edu 502686Sksewell@umich.edu 512686Sksewell@umich.eduBaseCache::BaseCache(const std::string &name, Params ¶ms) 522686Sksewell@umich.edu : MemObject(name), 532686Sksewell@umich.edu mshrQueue(params.numMSHRs, 4, MSHRQueue_MSHRs), 542686Sksewell@umich.edu writeBuffer(params.numWriteBuffers, params.numMSHRs+1000, 552686Sksewell@umich.edu MSHRQueue_WriteBuffer), 562686Sksewell@umich.edu blkSize(params.blkSize), 572686Sksewell@umich.edu numTarget(params.numTargets), 582686Sksewell@umich.edu blocked(0), 592686Sksewell@umich.edu noTargetMSHR(NULL), 602686Sksewell@umich.edu missCount(params.maxMisses), 612686Sksewell@umich.edu drainEvent(NULL) 622686Sksewell@umich.edu{ 632686Sksewell@umich.edu} 642686Sksewell@umich.edu 652686Sksewell@umich.edu 662686Sksewell@umich.eduvoid 672686Sksewell@umich.eduBaseCache::CachePort::recvStatusChange(Port::Status status) 682686Sksewell@umich.edu{ 692686Sksewell@umich.edu if (status == Port::RangeChange) { 702686Sksewell@umich.edu otherPort->sendStatusChange(Port::RangeChange); 712686Sksewell@umich.edu } 722686Sksewell@umich.edu} 732686Sksewell@umich.edu 742686Sksewell@umich.eduint 752686Sksewell@umich.eduBaseCache::CachePort::deviceBlockSize() 762686Sksewell@umich.edu{ 772686Sksewell@umich.edu return cache->getBlockSize(); 782686Sksewell@umich.edu} 792686Sksewell@umich.edu 802686Sksewell@umich.edu 812686Sksewell@umich.eduvoid 822686Sksewell@umich.eduBaseCache::CachePort::checkAndSendFunctional(PacketPtr pkt) 832686Sksewell@umich.edu{ 842686Sksewell@umich.edu checkFunctional(pkt); 852686Sksewell@umich.edu if (pkt->result != Packet::Success) 862686Sksewell@umich.edu sendFunctional(pkt); 872686Sksewell@umich.edu} 882686Sksewell@umich.edu 892686Sksewell@umich.edu 902686Sksewell@umich.edubool 912686Sksewell@umich.eduBaseCache::CachePort::recvRetryCommon() 922686Sksewell@umich.edu{ 932686Sksewell@umich.edu assert(waitingOnRetry); 942686Sksewell@umich.edu waitingOnRetry = false; 952686Sksewell@umich.edu return false; 962686Sksewell@umich.edu} 972686Sksewell@umich.edu 982686Sksewell@umich.edu 992686Sksewell@umich.eduvoid 1002686Sksewell@umich.eduBaseCache::CachePort::setBlocked() 1012686Sksewell@umich.edu{ 1022686Sksewell@umich.edu assert(!blocked); 1032686Sksewell@umich.edu DPRINTF(Cache, "Cache Blocking\n"); 1042686Sksewell@umich.edu blocked = true; 1052686Sksewell@umich.edu //Clear the retry flag 1062686Sksewell@umich.edu mustSendRetry = false; 1072686Sksewell@umich.edu} 1082686Sksewell@umich.edu 1092686Sksewell@umich.eduvoid 1102686Sksewell@umich.eduBaseCache::CachePort::clearBlocked() 1112686Sksewell@umich.edu{ 1122686Sksewell@umich.edu assert(blocked); 1132686Sksewell@umich.edu DPRINTF(Cache, "Cache Unblocking\n"); 1142686Sksewell@umich.edu blocked = false; 1152686Sksewell@umich.edu if (mustSendRetry) 1162686Sksewell@umich.edu { 1172686Sksewell@umich.edu DPRINTF(Cache, "Cache Sending Retry\n"); 1182686Sksewell@umich.edu mustSendRetry = false; 1192686Sksewell@umich.edu sendRetry(); 1202686Sksewell@umich.edu } 1212686Sksewell@umich.edu} 1222686Sksewell@umich.edu 1232686Sksewell@umich.edu 1242686Sksewell@umich.eduvoid 1252686Sksewell@umich.eduBaseCache::init() 1262686Sksewell@umich.edu{ 1272686Sksewell@umich.edu if (!cpuSidePort || !memSidePort) 1282686Sksewell@umich.edu panic("Cache not hooked up on both sides\n"); 1292686Sksewell@umich.edu cpuSidePort->sendStatusChange(Port::RangeChange); 1302686Sksewell@umich.edu} 1312686Sksewell@umich.edu 1322686Sksewell@umich.edu 1332686Sksewell@umich.eduvoid 1342686Sksewell@umich.eduBaseCache::regStats() 1352686Sksewell@umich.edu{ 1362686Sksewell@umich.edu using namespace Stats; 1372686Sksewell@umich.edu 1382686Sksewell@umich.edu // Hit statistics 1392686Sksewell@umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1402686Sksewell@umich.edu MemCmd cmd(access_idx); 1412686Sksewell@umich.edu const string &cstr = cmd.toString(); 1422686Sksewell@umich.edu 1432686Sksewell@umich.edu hits[access_idx] 1442686Sksewell@umich.edu .init(maxThreadsPerCPU) 1452686Sksewell@umich.edu .name(name() + "." + cstr + "_hits") 1462686Sksewell@umich.edu .desc("number of " + cstr + " hits") 1472686Sksewell@umich.edu .flags(total | nozero | nonan) 1482686Sksewell@umich.edu ; 1492686Sksewell@umich.edu } 1502686Sksewell@umich.edu 1512686Sksewell@umich.edu demandHits 1522686Sksewell@umich.edu .name(name() + ".demand_hits") 1532686Sksewell@umich.edu .desc("number of demand (read+write) hits") 1542686Sksewell@umich.edu .flags(total) 1552686Sksewell@umich.edu ; 1562686Sksewell@umich.edu demandHits = hits[MemCmd::ReadReq] + hits[MemCmd::WriteReq]; 1572686Sksewell@umich.edu 1582686Sksewell@umich.edu overallHits 1592686Sksewell@umich.edu .name(name() + ".overall_hits") 1602686Sksewell@umich.edu .desc("number of overall hits") 1612686Sksewell@umich.edu .flags(total) 1622686Sksewell@umich.edu ; 1632686Sksewell@umich.edu overallHits = demandHits + hits[MemCmd::SoftPFReq] + hits[MemCmd::HardPFReq] 1642686Sksewell@umich.edu + hits[MemCmd::Writeback]; 1652686Sksewell@umich.edu 1662686Sksewell@umich.edu // Miss statistics 1672686Sksewell@umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1682686Sksewell@umich.edu MemCmd cmd(access_idx); 1692686Sksewell@umich.edu const string &cstr = cmd.toString(); 1702686Sksewell@umich.edu 1712686Sksewell@umich.edu misses[access_idx] 1722686Sksewell@umich.edu .init(maxThreadsPerCPU) 1732686Sksewell@umich.edu .name(name() + "." + cstr + "_misses") 1742686Sksewell@umich.edu .desc("number of " + cstr + " misses") 1752686Sksewell@umich.edu .flags(total | nozero | nonan) 1762686Sksewell@umich.edu ; 1772686Sksewell@umich.edu } 1782686Sksewell@umich.edu 1792686Sksewell@umich.edu demandMisses 1802686Sksewell@umich.edu .name(name() + ".demand_misses") 1812686Sksewell@umich.edu .desc("number of demand (read+write) misses") 1822686Sksewell@umich.edu .flags(total) 1832686Sksewell@umich.edu ; 1842686Sksewell@umich.edu demandMisses = misses[MemCmd::ReadReq] + misses[MemCmd::WriteReq]; 1852686Sksewell@umich.edu 1862686Sksewell@umich.edu overallMisses 1872686Sksewell@umich.edu .name(name() + ".overall_misses") 1882686Sksewell@umich.edu .desc("number of overall misses") 1892686Sksewell@umich.edu .flags(total) 1902686Sksewell@umich.edu ; 1912686Sksewell@umich.edu overallMisses = demandMisses + misses[MemCmd::SoftPFReq] + 1922686Sksewell@umich.edu misses[MemCmd::HardPFReq] + misses[MemCmd::Writeback]; 1932686Sksewell@umich.edu 1942686Sksewell@umich.edu // Miss latency statistics 1952686Sksewell@umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1962686Sksewell@umich.edu MemCmd cmd(access_idx); 1972686Sksewell@umich.edu const string &cstr = cmd.toString(); 1982686Sksewell@umich.edu 1992686Sksewell@umich.edu missLatency[access_idx] 2002686Sksewell@umich.edu .init(maxThreadsPerCPU) 2012686Sksewell@umich.edu .name(name() + "." + cstr + "_miss_latency") 2022686Sksewell@umich.edu .desc("number of " + cstr + " miss cycles") 2032686Sksewell@umich.edu .flags(total | nozero | nonan) 2042686Sksewell@umich.edu ; 2052686Sksewell@umich.edu } 2064661Sksewell@umich.edu 2074661Sksewell@umich.edu demandMissLatency 2084661Sksewell@umich.edu .name(name() + ".demand_miss_latency") 2094661Sksewell@umich.edu .desc("number of demand (read+write) miss cycles") 2104661Sksewell@umich.edu .flags(total) 2114661Sksewell@umich.edu ; 212 demandMissLatency = missLatency[MemCmd::ReadReq] + missLatency[MemCmd::WriteReq]; 213 214 overallMissLatency 215 .name(name() + ".overall_miss_latency") 216 .desc("number of overall miss cycles") 217 .flags(total) 218 ; 219 overallMissLatency = demandMissLatency + missLatency[MemCmd::SoftPFReq] + 220 missLatency[MemCmd::HardPFReq]; 221 222 // access formulas 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 accesses[access_idx] 228 .name(name() + "." + cstr + "_accesses") 229 .desc("number of " + cstr + " accesses(hits+misses)") 230 .flags(total | nozero | nonan) 231 ; 232 233 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 234 } 235 236 demandAccesses 237 .name(name() + ".demand_accesses") 238 .desc("number of demand (read+write) accesses") 239 .flags(total) 240 ; 241 demandAccesses = demandHits + demandMisses; 242 243 overallAccesses 244 .name(name() + ".overall_accesses") 245 .desc("number of overall (read+write) accesses") 246 .flags(total) 247 ; 248 overallAccesses = overallHits + overallMisses; 249 250 // miss rate formulas 251 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 252 MemCmd cmd(access_idx); 253 const string &cstr = cmd.toString(); 254 255 missRate[access_idx] 256 .name(name() + "." + cstr + "_miss_rate") 257 .desc("miss rate for " + cstr + " accesses") 258 .flags(total | nozero | nonan) 259 ; 260 261 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 262 } 263 264 demandMissRate 265 .name(name() + ".demand_miss_rate") 266 .desc("miss rate for demand accesses") 267 .flags(total) 268 ; 269 demandMissRate = demandMisses / demandAccesses; 270 271 overallMissRate 272 .name(name() + ".overall_miss_rate") 273 .desc("miss rate for overall accesses") 274 .flags(total) 275 ; 276 overallMissRate = overallMisses / overallAccesses; 277 278 // miss latency formulas 279 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 280 MemCmd cmd(access_idx); 281 const string &cstr = cmd.toString(); 282 283 avgMissLatency[access_idx] 284 .name(name() + "." + cstr + "_avg_miss_latency") 285 .desc("average " + cstr + " miss latency") 286 .flags(total | nozero | nonan) 287 ; 288 289 avgMissLatency[access_idx] = 290 missLatency[access_idx] / misses[access_idx]; 291 } 292 293 demandAvgMissLatency 294 .name(name() + ".demand_avg_miss_latency") 295 .desc("average overall miss latency") 296 .flags(total) 297 ; 298 demandAvgMissLatency = demandMissLatency / demandMisses; 299 300 overallAvgMissLatency 301 .name(name() + ".overall_avg_miss_latency") 302 .desc("average overall miss latency") 303 .flags(total) 304 ; 305 overallAvgMissLatency = overallMissLatency / overallMisses; 306 307 blocked_cycles.init(NUM_BLOCKED_CAUSES); 308 blocked_cycles 309 .name(name() + ".blocked_cycles") 310 .desc("number of cycles access was blocked") 311 .subname(Blocked_NoMSHRs, "no_mshrs") 312 .subname(Blocked_NoTargets, "no_targets") 313 ; 314 315 316 blocked_causes.init(NUM_BLOCKED_CAUSES); 317 blocked_causes 318 .name(name() + ".blocked") 319 .desc("number of cycles access was blocked") 320 .subname(Blocked_NoMSHRs, "no_mshrs") 321 .subname(Blocked_NoTargets, "no_targets") 322 ; 323 324 avg_blocked 325 .name(name() + ".avg_blocked_cycles") 326 .desc("average number of cycles each access was blocked") 327 .subname(Blocked_NoMSHRs, "no_mshrs") 328 .subname(Blocked_NoTargets, "no_targets") 329 ; 330 331 avg_blocked = blocked_cycles / blocked_causes; 332 333 fastWrites 334 .name(name() + ".fast_writes") 335 .desc("number of fast writes performed") 336 ; 337 338 cacheCopies 339 .name(name() + ".cache_copies") 340 .desc("number of cache copies performed") 341 ; 342 343 writebacks 344 .init(maxThreadsPerCPU) 345 .name(name() + ".writebacks") 346 .desc("number of writebacks") 347 .flags(total) 348 ; 349 350 // MSHR statistics 351 // MSHR hit statistics 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 mshr_hits[access_idx] 357 .init(maxThreadsPerCPU) 358 .name(name() + "." + cstr + "_mshr_hits") 359 .desc("number of " + cstr + " MSHR hits") 360 .flags(total | nozero | nonan) 361 ; 362 } 363 364 demandMshrHits 365 .name(name() + ".demand_mshr_hits") 366 .desc("number of demand (read+write) MSHR hits") 367 .flags(total) 368 ; 369 demandMshrHits = mshr_hits[MemCmd::ReadReq] + mshr_hits[MemCmd::WriteReq]; 370 371 overallMshrHits 372 .name(name() + ".overall_mshr_hits") 373 .desc("number of overall MSHR hits") 374 .flags(total) 375 ; 376 overallMshrHits = demandMshrHits + mshr_hits[MemCmd::SoftPFReq] + 377 mshr_hits[MemCmd::HardPFReq]; 378 379 // MSHR miss statistics 380 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 381 MemCmd cmd(access_idx); 382 const string &cstr = cmd.toString(); 383 384 mshr_misses[access_idx] 385 .init(maxThreadsPerCPU) 386 .name(name() + "." + cstr + "_mshr_misses") 387 .desc("number of " + cstr + " MSHR misses") 388 .flags(total | nozero | nonan) 389 ; 390 } 391 392 demandMshrMisses 393 .name(name() + ".demand_mshr_misses") 394 .desc("number of demand (read+write) MSHR misses") 395 .flags(total) 396 ; 397 demandMshrMisses = mshr_misses[MemCmd::ReadReq] + mshr_misses[MemCmd::WriteReq]; 398 399 overallMshrMisses 400 .name(name() + ".overall_mshr_misses") 401 .desc("number of overall MSHR misses") 402 .flags(total) 403 ; 404 overallMshrMisses = demandMshrMisses + mshr_misses[MemCmd::SoftPFReq] + 405 mshr_misses[MemCmd::HardPFReq]; 406 407 // MSHR miss latency statistics 408 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 409 MemCmd cmd(access_idx); 410 const string &cstr = cmd.toString(); 411 412 mshr_miss_latency[access_idx] 413 .init(maxThreadsPerCPU) 414 .name(name() + "." + cstr + "_mshr_miss_latency") 415 .desc("number of " + cstr + " MSHR miss cycles") 416 .flags(total | nozero | nonan) 417 ; 418 } 419 420 demandMshrMissLatency 421 .name(name() + ".demand_mshr_miss_latency") 422 .desc("number of demand (read+write) MSHR miss cycles") 423 .flags(total) 424 ; 425 demandMshrMissLatency = mshr_miss_latency[MemCmd::ReadReq] 426 + mshr_miss_latency[MemCmd::WriteReq]; 427 428 overallMshrMissLatency 429 .name(name() + ".overall_mshr_miss_latency") 430 .desc("number of overall MSHR miss cycles") 431 .flags(total) 432 ; 433 overallMshrMissLatency = demandMshrMissLatency + 434 mshr_miss_latency[MemCmd::SoftPFReq] + mshr_miss_latency[MemCmd::HardPFReq]; 435 436 // MSHR uncacheable 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_uncacheable[access_idx] 442 .init(maxThreadsPerCPU) 443 .name(name() + "." + cstr + "_mshr_uncacheable") 444 .desc("number of " + cstr + " MSHR uncacheable") 445 .flags(total | nozero | nonan) 446 ; 447 } 448 449 overallMshrUncacheable 450 .name(name() + ".overall_mshr_uncacheable_misses") 451 .desc("number of overall MSHR uncacheable misses") 452 .flags(total) 453 ; 454 overallMshrUncacheable = mshr_uncacheable[MemCmd::ReadReq] 455 + mshr_uncacheable[MemCmd::WriteReq] + mshr_uncacheable[MemCmd::SoftPFReq] 456 + mshr_uncacheable[MemCmd::HardPFReq]; 457 458 // MSHR miss latency statistics 459 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 460 MemCmd cmd(access_idx); 461 const string &cstr = cmd.toString(); 462 463 mshr_uncacheable_lat[access_idx] 464 .init(maxThreadsPerCPU) 465 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 466 .desc("number of " + cstr + " MSHR uncacheable cycles") 467 .flags(total | nozero | nonan) 468 ; 469 } 470 471 overallMshrUncacheableLatency 472 .name(name() + ".overall_mshr_uncacheable_latency") 473 .desc("number of overall MSHR uncacheable cycles") 474 .flags(total) 475 ; 476 overallMshrUncacheableLatency = mshr_uncacheable_lat[MemCmd::ReadReq] 477 + mshr_uncacheable_lat[MemCmd::WriteReq] 478 + mshr_uncacheable_lat[MemCmd::SoftPFReq] 479 + mshr_uncacheable_lat[MemCmd::HardPFReq]; 480 481#if 0 482 // MSHR access formulas 483 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 484 MemCmd cmd(access_idx); 485 const string &cstr = cmd.toString(); 486 487 mshrAccesses[access_idx] 488 .name(name() + "." + cstr + "_mshr_accesses") 489 .desc("number of " + cstr + " mshr accesses(hits+misses)") 490 .flags(total | nozero | nonan) 491 ; 492 mshrAccesses[access_idx] = 493 mshr_hits[access_idx] + mshr_misses[access_idx] 494 + mshr_uncacheable[access_idx]; 495 } 496 497 demandMshrAccesses 498 .name(name() + ".demand_mshr_accesses") 499 .desc("number of demand (read+write) mshr accesses") 500 .flags(total | nozero | nonan) 501 ; 502 demandMshrAccesses = demandMshrHits + demandMshrMisses; 503 504 overallMshrAccesses 505 .name(name() + ".overall_mshr_accesses") 506 .desc("number of overall (read+write) mshr accesses") 507 .flags(total | nozero | nonan) 508 ; 509 overallMshrAccesses = overallMshrHits + overallMshrMisses 510 + overallMshrUncacheable; 511#endif 512 513 // MSHR miss rate formulas 514 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 515 MemCmd cmd(access_idx); 516 const string &cstr = cmd.toString(); 517 518 mshrMissRate[access_idx] 519 .name(name() + "." + cstr + "_mshr_miss_rate") 520 .desc("mshr miss rate for " + cstr + " accesses") 521 .flags(total | nozero | nonan) 522 ; 523 524 mshrMissRate[access_idx] = 525 mshr_misses[access_idx] / accesses[access_idx]; 526 } 527 528 demandMshrMissRate 529 .name(name() + ".demand_mshr_miss_rate") 530 .desc("mshr miss rate for demand accesses") 531 .flags(total) 532 ; 533 demandMshrMissRate = demandMshrMisses / demandAccesses; 534 535 overallMshrMissRate 536 .name(name() + ".overall_mshr_miss_rate") 537 .desc("mshr miss rate for overall accesses") 538 .flags(total) 539 ; 540 overallMshrMissRate = overallMshrMisses / overallAccesses; 541 542 // mshrMiss latency formulas 543 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 544 MemCmd cmd(access_idx); 545 const string &cstr = cmd.toString(); 546 547 avgMshrMissLatency[access_idx] 548 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 549 .desc("average " + cstr + " mshr miss latency") 550 .flags(total | nozero | nonan) 551 ; 552 553 avgMshrMissLatency[access_idx] = 554 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 555 } 556 557 demandAvgMshrMissLatency 558 .name(name() + ".demand_avg_mshr_miss_latency") 559 .desc("average overall mshr miss latency") 560 .flags(total) 561 ; 562 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 563 564 overallAvgMshrMissLatency 565 .name(name() + ".overall_avg_mshr_miss_latency") 566 .desc("average overall mshr miss latency") 567 .flags(total) 568 ; 569 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 570 571 // mshrUncacheable latency formulas 572 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 573 MemCmd cmd(access_idx); 574 const string &cstr = cmd.toString(); 575 576 avgMshrUncacheableLatency[access_idx] 577 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 578 .desc("average " + cstr + " mshr uncacheable latency") 579 .flags(total | nozero | nonan) 580 ; 581 582 avgMshrUncacheableLatency[access_idx] = 583 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 584 } 585 586 overallAvgMshrUncacheableLatency 587 .name(name() + ".overall_avg_mshr_uncacheable_latency") 588 .desc("average overall mshr uncacheable latency") 589 .flags(total) 590 ; 591 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 592 593 mshr_cap_events 594 .init(maxThreadsPerCPU) 595 .name(name() + ".mshr_cap_events") 596 .desc("number of times MSHR cap was activated") 597 .flags(total) 598 ; 599 600 //software prefetching stats 601 soft_prefetch_mshr_full 602 .init(maxThreadsPerCPU) 603 .name(name() + ".soft_prefetch_mshr_full") 604 .desc("number of mshr full events for SW prefetching instrutions") 605 .flags(total) 606 ; 607 608 mshr_no_allocate_misses 609 .name(name() +".no_allocate_misses") 610 .desc("Number of misses that were no-allocate") 611 ; 612 613} 614 615unsigned int 616BaseCache::drain(Event *de) 617{ 618 int count = memSidePort->drain(de) + cpuSidePort->drain(de); 619 620 // Set status 621 if (count != 0) { 622 drainEvent = de; 623 624 changeState(SimObject::Draining); 625 return count; 626 } 627 628 changeState(SimObject::Drained); 629 return 0; 630} 631