base.cc revision 8232
19651SAndreas.Sandberg@ARM.com/* 29651SAndreas.Sandberg@ARM.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 39651SAndreas.Sandberg@ARM.com * All rights reserved. 49651SAndreas.Sandberg@ARM.com * 59651SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 69651SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 79651SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 89651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 99651SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 109651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 119651SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 129651SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 139651SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 149651SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 159651SAndreas.Sandberg@ARM.com * 169651SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179651SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189651SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199651SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209651SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219651SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229651SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239651SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249651SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259651SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269651SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279651SAndreas.Sandberg@ARM.com * 289651SAndreas.Sandberg@ARM.com * Authors: Erik Hallnor 299651SAndreas.Sandberg@ARM.com */ 309651SAndreas.Sandberg@ARM.com 319651SAndreas.Sandberg@ARM.com/** 329651SAndreas.Sandberg@ARM.com * @file 339651SAndreas.Sandberg@ARM.com * Definition of BaseCache functions. 349651SAndreas.Sandberg@ARM.com */ 359651SAndreas.Sandberg@ARM.com 369651SAndreas.Sandberg@ARM.com#include "cpu/base.hh" 379651SAndreas.Sandberg@ARM.com#include "cpu/smt.hh" 389651SAndreas.Sandberg@ARM.com#include "debug/Cache.hh" 399651SAndreas.Sandberg@ARM.com#include "mem/cache/base.hh" 4011793Sbrandon.potter@amd.com#include "mem/cache/mshr.hh" 419651SAndreas.Sandberg@ARM.com 429651SAndreas.Sandberg@ARM.comusing namespace std; 439651SAndreas.Sandberg@ARM.com 449651SAndreas.Sandberg@ARM.comBaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache, 459651SAndreas.Sandberg@ARM.com const std::string &_label) 469651SAndreas.Sandberg@ARM.com : SimpleTimingPort(_name, _cache), cache(_cache), 479651SAndreas.Sandberg@ARM.com label(_label), otherPort(NULL), 489651SAndreas.Sandberg@ARM.com blocked(false), mustSendRetry(false) 499651SAndreas.Sandberg@ARM.com{ 509651SAndreas.Sandberg@ARM.com} 519651SAndreas.Sandberg@ARM.com 529651SAndreas.Sandberg@ARM.com 5312334Sgabeblack@google.comBaseCache::BaseCache(const Params *p) 549651SAndreas.Sandberg@ARM.com : MemObject(p), 559651SAndreas.Sandberg@ARM.com mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs), 569651SAndreas.Sandberg@ARM.com writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 579651SAndreas.Sandberg@ARM.com MSHRQueue_WriteBuffer), 589651SAndreas.Sandberg@ARM.com blkSize(p->block_size), 599651SAndreas.Sandberg@ARM.com hitLatency(p->latency), 609651SAndreas.Sandberg@ARM.com numTarget(p->tgts_per_mshr), 619651SAndreas.Sandberg@ARM.com forwardSnoops(p->forward_snoops), 629651SAndreas.Sandberg@ARM.com isTopLevel(p->is_top_level), 639651SAndreas.Sandberg@ARM.com blocked(0), 649651SAndreas.Sandberg@ARM.com noTargetMSHR(NULL), 659651SAndreas.Sandberg@ARM.com missCount(p->max_miss_count), 669651SAndreas.Sandberg@ARM.com drainEvent(NULL), 679651SAndreas.Sandberg@ARM.com addrRange(p->addr_range), 689651SAndreas.Sandberg@ARM.com _numCpus(p->num_cpus) 699651SAndreas.Sandberg@ARM.com{ 709651SAndreas.Sandberg@ARM.com} 719651SAndreas.Sandberg@ARM.com 729651SAndreas.Sandberg@ARM.comvoid 739651SAndreas.Sandberg@ARM.comBaseCache::CachePort::recvStatusChange(Port::Status status) 749651SAndreas.Sandberg@ARM.com{ 759651SAndreas.Sandberg@ARM.com if (status == Port::RangeChange) { 769651SAndreas.Sandberg@ARM.com otherPort->sendStatusChange(Port::RangeChange); 779651SAndreas.Sandberg@ARM.com } 789651SAndreas.Sandberg@ARM.com} 799651SAndreas.Sandberg@ARM.com 809651SAndreas.Sandberg@ARM.com 819651SAndreas.Sandberg@ARM.combool 829651SAndreas.Sandberg@ARM.comBaseCache::CachePort::checkFunctional(PacketPtr pkt) 839651SAndreas.Sandberg@ARM.com{ 849651SAndreas.Sandberg@ARM.com pkt->pushLabel(label); 859651SAndreas.Sandberg@ARM.com bool done = SimpleTimingPort::checkFunctional(pkt); 869651SAndreas.Sandberg@ARM.com pkt->popLabel(); 879651SAndreas.Sandberg@ARM.com return done; 889651SAndreas.Sandberg@ARM.com} 899651SAndreas.Sandberg@ARM.com 909651SAndreas.Sandberg@ARM.com 919651SAndreas.Sandberg@ARM.comunsigned 929651SAndreas.Sandberg@ARM.comBaseCache::CachePort::deviceBlockSize() const 939651SAndreas.Sandberg@ARM.com{ 949651SAndreas.Sandberg@ARM.com return cache->getBlockSize(); 959651SAndreas.Sandberg@ARM.com} 969651SAndreas.Sandberg@ARM.com 979651SAndreas.Sandberg@ARM.com 989651SAndreas.Sandberg@ARM.combool 999651SAndreas.Sandberg@ARM.comBaseCache::CachePort::recvRetryCommon() 1009651SAndreas.Sandberg@ARM.com{ 1019651SAndreas.Sandberg@ARM.com assert(waitingOnRetry); 1029651SAndreas.Sandberg@ARM.com waitingOnRetry = false; 1039651SAndreas.Sandberg@ARM.com return false; 1049651SAndreas.Sandberg@ARM.com} 1059651SAndreas.Sandberg@ARM.com 1069651SAndreas.Sandberg@ARM.com 1079651SAndreas.Sandberg@ARM.comvoid 1089651SAndreas.Sandberg@ARM.comBaseCache::CachePort::setBlocked() 1099651SAndreas.Sandberg@ARM.com{ 1109651SAndreas.Sandberg@ARM.com assert(!blocked); 1119651SAndreas.Sandberg@ARM.com DPRINTF(Cache, "Cache Blocking\n"); 1129651SAndreas.Sandberg@ARM.com blocked = true; 1139651SAndreas.Sandberg@ARM.com //Clear the retry flag 1149651SAndreas.Sandberg@ARM.com mustSendRetry = false; 1159651SAndreas.Sandberg@ARM.com} 1169651SAndreas.Sandberg@ARM.com 1179651SAndreas.Sandberg@ARM.comvoid 1189651SAndreas.Sandberg@ARM.comBaseCache::CachePort::clearBlocked() 1199651SAndreas.Sandberg@ARM.com{ 1209651SAndreas.Sandberg@ARM.com assert(blocked); 1219651SAndreas.Sandberg@ARM.com DPRINTF(Cache, "Cache Unblocking\n"); 1229651SAndreas.Sandberg@ARM.com blocked = false; 1239651SAndreas.Sandberg@ARM.com if (mustSendRetry) 1249651SAndreas.Sandberg@ARM.com { 1259651SAndreas.Sandberg@ARM.com DPRINTF(Cache, "Cache Sending Retry\n"); 1269651SAndreas.Sandberg@ARM.com mustSendRetry = false; 1279651SAndreas.Sandberg@ARM.com SendRetryEvent *ev = new SendRetryEvent(this, true); 1289651SAndreas.Sandberg@ARM.com // @TODO: need to find a better time (next bus cycle?) 1299651SAndreas.Sandberg@ARM.com schedule(ev, curTick() + 1); 1309651SAndreas.Sandberg@ARM.com } 1319651SAndreas.Sandberg@ARM.com} 1329651SAndreas.Sandberg@ARM.com 1339651SAndreas.Sandberg@ARM.com 1349651SAndreas.Sandberg@ARM.comvoid 1359651SAndreas.Sandberg@ARM.comBaseCache::init() 1369651SAndreas.Sandberg@ARM.com{ 1379651SAndreas.Sandberg@ARM.com if (!cpuSidePort || !memSidePort) 1389651SAndreas.Sandberg@ARM.com panic("Cache not hooked up on both sides\n"); 1399651SAndreas.Sandberg@ARM.com cpuSidePort->sendStatusChange(Port::RangeChange); 1409651SAndreas.Sandberg@ARM.com} 1419651SAndreas.Sandberg@ARM.com 1429651SAndreas.Sandberg@ARM.com 1439651SAndreas.Sandberg@ARM.comvoid 1449651SAndreas.Sandberg@ARM.comBaseCache::regStats() 1459651SAndreas.Sandberg@ARM.com{ 1469651SAndreas.Sandberg@ARM.com using namespace Stats; 1479651SAndreas.Sandberg@ARM.com 1489651SAndreas.Sandberg@ARM.com // Hit statistics 1499651SAndreas.Sandberg@ARM.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1509651SAndreas.Sandberg@ARM.com MemCmd cmd(access_idx); 1519651SAndreas.Sandberg@ARM.com const string &cstr = cmd.toString(); 1529651SAndreas.Sandberg@ARM.com 1539651SAndreas.Sandberg@ARM.com hits[access_idx] 1549651SAndreas.Sandberg@ARM.com#if FULL_SYSTEM 1559651SAndreas.Sandberg@ARM.com .init(_numCpus + 1) 1569651SAndreas.Sandberg@ARM.com#else 1579651SAndreas.Sandberg@ARM.com .init(_numCpus) 1589651SAndreas.Sandberg@ARM.com#endif 1599651SAndreas.Sandberg@ARM.com .name(name() + "." + cstr + "_hits") 1609651SAndreas.Sandberg@ARM.com .desc("number of " + cstr + " hits") 1619651SAndreas.Sandberg@ARM.com .flags(total | nozero | nonan) 1629651SAndreas.Sandberg@ARM.com ; 1639651SAndreas.Sandberg@ARM.com } 1649651SAndreas.Sandberg@ARM.com 1659651SAndreas.Sandberg@ARM.com// These macros make it easier to sum the right subset of commands and 1669651SAndreas.Sandberg@ARM.com// to change the subset of commands that are considered "demand" vs 1679651SAndreas.Sandberg@ARM.com// "non-demand" 1689651SAndreas.Sandberg@ARM.com#define SUM_DEMAND(s) \ 1699651SAndreas.Sandberg@ARM.com (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq]) 1709651SAndreas.Sandberg@ARM.com 1719651SAndreas.Sandberg@ARM.com// should writebacks be included here? prior code was inconsistent... 17213787Sgambordr@oregonstate.edu#define SUM_NON_DEMAND(s) \ 17313787Sgambordr@oregonstate.edu (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 17413787Sgambordr@oregonstate.edu 17513787Sgambordr@oregonstate.edu demandHits 17613787Sgambordr@oregonstate.edu .name(name() + ".demand_hits") 17713787Sgambordr@oregonstate.edu .desc("number of demand (read+write) hits") 17813787Sgambordr@oregonstate.edu .flags(total) 17913787Sgambordr@oregonstate.edu ; 18013787Sgambordr@oregonstate.edu demandHits = SUM_DEMAND(hits); 18113787Sgambordr@oregonstate.edu 18213787Sgambordr@oregonstate.edu overallHits 18313787Sgambordr@oregonstate.edu .name(name() + ".overall_hits") 1849651SAndreas.Sandberg@ARM.com .desc("number of overall hits") 1859651SAndreas.Sandberg@ARM.com .flags(total) 1869651SAndreas.Sandberg@ARM.com ; 1879651SAndreas.Sandberg@ARM.com overallHits = demandHits + SUM_NON_DEMAND(hits); 1889651SAndreas.Sandberg@ARM.com 1899651SAndreas.Sandberg@ARM.com // Miss statistics 1909651SAndreas.Sandberg@ARM.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1919651SAndreas.Sandberg@ARM.com MemCmd cmd(access_idx); 1929651SAndreas.Sandberg@ARM.com const string &cstr = cmd.toString(); 1939651SAndreas.Sandberg@ARM.com 1949651SAndreas.Sandberg@ARM.com misses[access_idx] 1959651SAndreas.Sandberg@ARM.com#if FULL_SYSTEM 1969651SAndreas.Sandberg@ARM.com .init(_numCpus + 1) 1979651SAndreas.Sandberg@ARM.com#else 1989651SAndreas.Sandberg@ARM.com .init(_numCpus) 1999651SAndreas.Sandberg@ARM.com#endif 2009651SAndreas.Sandberg@ARM.com .name(name() + "." + cstr + "_misses") 2019651SAndreas.Sandberg@ARM.com .desc("number of " + cstr + " misses") 2029651SAndreas.Sandberg@ARM.com .flags(total | nozero | nonan) 2039651SAndreas.Sandberg@ARM.com ; 2049651SAndreas.Sandberg@ARM.com } 2059651SAndreas.Sandberg@ARM.com 2069651SAndreas.Sandberg@ARM.com demandMisses 2079651SAndreas.Sandberg@ARM.com .name(name() + ".demand_misses") 2089651SAndreas.Sandberg@ARM.com .desc("number of demand (read+write) misses") 2099651SAndreas.Sandberg@ARM.com .flags(total) 2109651SAndreas.Sandberg@ARM.com ; 2119651SAndreas.Sandberg@ARM.com demandMisses = SUM_DEMAND(misses); 2129651SAndreas.Sandberg@ARM.com 2139651SAndreas.Sandberg@ARM.com overallMisses 2149651SAndreas.Sandberg@ARM.com .name(name() + ".overall_misses") 2159651SAndreas.Sandberg@ARM.com .desc("number of overall misses") 2169651SAndreas.Sandberg@ARM.com .flags(total) 2179651SAndreas.Sandberg@ARM.com ; 2189651SAndreas.Sandberg@ARM.com overallMisses = demandMisses + SUM_NON_DEMAND(misses); 2199651SAndreas.Sandberg@ARM.com 2209651SAndreas.Sandberg@ARM.com // Miss latency statistics 2219651SAndreas.Sandberg@ARM.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 2229651SAndreas.Sandberg@ARM.com MemCmd cmd(access_idx); 2239651SAndreas.Sandberg@ARM.com const string &cstr = cmd.toString(); 2249651SAndreas.Sandberg@ARM.com 2259651SAndreas.Sandberg@ARM.com missLatency[access_idx] 2269651SAndreas.Sandberg@ARM.com .init(maxThreadsPerCPU) 2279651SAndreas.Sandberg@ARM.com .name(name() + "." + cstr + "_miss_latency") 2289651SAndreas.Sandberg@ARM.com .desc("number of " + cstr + " miss cycles") 2299651SAndreas.Sandberg@ARM.com .flags(total | nozero | nonan) 2309651SAndreas.Sandberg@ARM.com ; 2319651SAndreas.Sandberg@ARM.com } 2329651SAndreas.Sandberg@ARM.com 2339651SAndreas.Sandberg@ARM.com demandMissLatency 2349651SAndreas.Sandberg@ARM.com .name(name() + ".demand_miss_latency") 2359651SAndreas.Sandberg@ARM.com .desc("number of demand (read+write) miss cycles") 2369651SAndreas.Sandberg@ARM.com .flags(total) 2379651SAndreas.Sandberg@ARM.com ; 2389651SAndreas.Sandberg@ARM.com demandMissLatency = SUM_DEMAND(missLatency); 2399651SAndreas.Sandberg@ARM.com 2409651SAndreas.Sandberg@ARM.com overallMissLatency 2419651SAndreas.Sandberg@ARM.com .name(name() + ".overall_miss_latency") 2429651SAndreas.Sandberg@ARM.com .desc("number of overall miss cycles") 2439651SAndreas.Sandberg@ARM.com .flags(total) 2449651SAndreas.Sandberg@ARM.com ; 2459651SAndreas.Sandberg@ARM.com overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 2469651SAndreas.Sandberg@ARM.com 2479651SAndreas.Sandberg@ARM.com // access formulas 2489651SAndreas.Sandberg@ARM.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 2499651SAndreas.Sandberg@ARM.com MemCmd cmd(access_idx); 2509651SAndreas.Sandberg@ARM.com const string &cstr = cmd.toString(); 2519651SAndreas.Sandberg@ARM.com 2529651SAndreas.Sandberg@ARM.com accesses[access_idx] 2539651SAndreas.Sandberg@ARM.com .name(name() + "." + cstr + "_accesses") 2549651SAndreas.Sandberg@ARM.com .desc("number of " + cstr + " accesses(hits+misses)") 2559651SAndreas.Sandberg@ARM.com .flags(total | nozero | nonan) 25611321Ssteve.reinhardt@amd.com ; 2579651SAndreas.Sandberg@ARM.com 258 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 259 } 260 261 demandAccesses 262 .name(name() + ".demand_accesses") 263 .desc("number of demand (read+write) accesses") 264 .flags(total) 265 ; 266 demandAccesses = demandHits + demandMisses; 267 268 overallAccesses 269 .name(name() + ".overall_accesses") 270 .desc("number of overall (read+write) accesses") 271 .flags(total) 272 ; 273 overallAccesses = overallHits + overallMisses; 274 275 // miss rate formulas 276 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 277 MemCmd cmd(access_idx); 278 const string &cstr = cmd.toString(); 279 280 missRate[access_idx] 281 .name(name() + "." + cstr + "_miss_rate") 282 .desc("miss rate for " + cstr + " accesses") 283 .flags(total | nozero | nonan) 284 ; 285 286 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 287 } 288 289 demandMissRate 290 .name(name() + ".demand_miss_rate") 291 .desc("miss rate for demand accesses") 292 .flags(total) 293 ; 294 demandMissRate = demandMisses / demandAccesses; 295 296 overallMissRate 297 .name(name() + ".overall_miss_rate") 298 .desc("miss rate for overall accesses") 299 .flags(total) 300 ; 301 overallMissRate = overallMisses / overallAccesses; 302 303 // miss latency formulas 304 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 305 MemCmd cmd(access_idx); 306 const string &cstr = cmd.toString(); 307 308 avgMissLatency[access_idx] 309 .name(name() + "." + cstr + "_avg_miss_latency") 310 .desc("average " + cstr + " miss latency") 311 .flags(total | nozero | nonan) 312 ; 313 314 avgMissLatency[access_idx] = 315 missLatency[access_idx] / misses[access_idx]; 316 } 317 318 demandAvgMissLatency 319 .name(name() + ".demand_avg_miss_latency") 320 .desc("average overall miss latency") 321 .flags(total) 322 ; 323 demandAvgMissLatency = demandMissLatency / demandMisses; 324 325 overallAvgMissLatency 326 .name(name() + ".overall_avg_miss_latency") 327 .desc("average overall miss latency") 328 .flags(total) 329 ; 330 overallAvgMissLatency = overallMissLatency / overallMisses; 331 332 blocked_cycles.init(NUM_BLOCKED_CAUSES); 333 blocked_cycles 334 .name(name() + ".blocked_cycles") 335 .desc("number of cycles access was blocked") 336 .subname(Blocked_NoMSHRs, "no_mshrs") 337 .subname(Blocked_NoTargets, "no_targets") 338 ; 339 340 341 blocked_causes.init(NUM_BLOCKED_CAUSES); 342 blocked_causes 343 .name(name() + ".blocked") 344 .desc("number of cycles access was blocked") 345 .subname(Blocked_NoMSHRs, "no_mshrs") 346 .subname(Blocked_NoTargets, "no_targets") 347 ; 348 349 avg_blocked 350 .name(name() + ".avg_blocked_cycles") 351 .desc("average number of cycles each access was blocked") 352 .subname(Blocked_NoMSHRs, "no_mshrs") 353 .subname(Blocked_NoTargets, "no_targets") 354 ; 355 356 avg_blocked = blocked_cycles / blocked_causes; 357 358 fastWrites 359 .name(name() + ".fast_writes") 360 .desc("number of fast writes performed") 361 ; 362 363 cacheCopies 364 .name(name() + ".cache_copies") 365 .desc("number of cache copies performed") 366 ; 367 368 writebacks 369 .init(maxThreadsPerCPU) 370 .name(name() + ".writebacks") 371 .desc("number of writebacks") 372 .flags(total) 373 ; 374 375 // MSHR statistics 376 // MSHR hit statistics 377 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 378 MemCmd cmd(access_idx); 379 const string &cstr = cmd.toString(); 380 381 mshr_hits[access_idx] 382 .init(maxThreadsPerCPU) 383 .name(name() + "." + cstr + "_mshr_hits") 384 .desc("number of " + cstr + " MSHR hits") 385 .flags(total | nozero | nonan) 386 ; 387 } 388 389 demandMshrHits 390 .name(name() + ".demand_mshr_hits") 391 .desc("number of demand (read+write) MSHR hits") 392 .flags(total) 393 ; 394 demandMshrHits = SUM_DEMAND(mshr_hits); 395 396 overallMshrHits 397 .name(name() + ".overall_mshr_hits") 398 .desc("number of overall MSHR hits") 399 .flags(total) 400 ; 401 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 402 403 // MSHR miss statistics 404 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 405 MemCmd cmd(access_idx); 406 const string &cstr = cmd.toString(); 407 408 mshr_misses[access_idx] 409 .init(maxThreadsPerCPU) 410 .name(name() + "." + cstr + "_mshr_misses") 411 .desc("number of " + cstr + " MSHR misses") 412 .flags(total | nozero | nonan) 413 ; 414 } 415 416 demandMshrMisses 417 .name(name() + ".demand_mshr_misses") 418 .desc("number of demand (read+write) MSHR misses") 419 .flags(total) 420 ; 421 demandMshrMisses = SUM_DEMAND(mshr_misses); 422 423 overallMshrMisses 424 .name(name() + ".overall_mshr_misses") 425 .desc("number of overall MSHR misses") 426 .flags(total) 427 ; 428 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 429 430 // MSHR miss latency statistics 431 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 432 MemCmd cmd(access_idx); 433 const string &cstr = cmd.toString(); 434 435 mshr_miss_latency[access_idx] 436 .init(maxThreadsPerCPU) 437 .name(name() + "." + cstr + "_mshr_miss_latency") 438 .desc("number of " + cstr + " MSHR miss cycles") 439 .flags(total | nozero | nonan) 440 ; 441 } 442 443 demandMshrMissLatency 444 .name(name() + ".demand_mshr_miss_latency") 445 .desc("number of demand (read+write) MSHR miss cycles") 446 .flags(total) 447 ; 448 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 449 450 overallMshrMissLatency 451 .name(name() + ".overall_mshr_miss_latency") 452 .desc("number of overall MSHR miss cycles") 453 .flags(total) 454 ; 455 overallMshrMissLatency = 456 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 457 458 // MSHR uncacheable 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[access_idx] 464 .init(maxThreadsPerCPU) 465 .name(name() + "." + cstr + "_mshr_uncacheable") 466 .desc("number of " + cstr + " MSHR uncacheable") 467 .flags(total | nozero | nonan) 468 ; 469 } 470 471 overallMshrUncacheable 472 .name(name() + ".overall_mshr_uncacheable_misses") 473 .desc("number of overall MSHR uncacheable misses") 474 .flags(total) 475 ; 476 overallMshrUncacheable = 477 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 478 479 // MSHR miss latency statistics 480 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 481 MemCmd cmd(access_idx); 482 const string &cstr = cmd.toString(); 483 484 mshr_uncacheable_lat[access_idx] 485 .init(maxThreadsPerCPU) 486 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 487 .desc("number of " + cstr + " MSHR uncacheable cycles") 488 .flags(total | nozero | nonan) 489 ; 490 } 491 492 overallMshrUncacheableLatency 493 .name(name() + ".overall_mshr_uncacheable_latency") 494 .desc("number of overall MSHR uncacheable cycles") 495 .flags(total) 496 ; 497 overallMshrUncacheableLatency = 498 SUM_DEMAND(mshr_uncacheable_lat) + 499 SUM_NON_DEMAND(mshr_uncacheable_lat); 500 501#if 0 502 // MSHR access formulas 503 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 504 MemCmd cmd(access_idx); 505 const string &cstr = cmd.toString(); 506 507 mshrAccesses[access_idx] 508 .name(name() + "." + cstr + "_mshr_accesses") 509 .desc("number of " + cstr + " mshr accesses(hits+misses)") 510 .flags(total | nozero | nonan) 511 ; 512 mshrAccesses[access_idx] = 513 mshr_hits[access_idx] + mshr_misses[access_idx] 514 + mshr_uncacheable[access_idx]; 515 } 516 517 demandMshrAccesses 518 .name(name() + ".demand_mshr_accesses") 519 .desc("number of demand (read+write) mshr accesses") 520 .flags(total | nozero | nonan) 521 ; 522 demandMshrAccesses = demandMshrHits + demandMshrMisses; 523 524 overallMshrAccesses 525 .name(name() + ".overall_mshr_accesses") 526 .desc("number of overall (read+write) mshr accesses") 527 .flags(total | nozero | nonan) 528 ; 529 overallMshrAccesses = overallMshrHits + overallMshrMisses 530 + overallMshrUncacheable; 531#endif 532 533 // MSHR miss rate formulas 534 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 535 MemCmd cmd(access_idx); 536 const string &cstr = cmd.toString(); 537 538 mshrMissRate[access_idx] 539 .name(name() + "." + cstr + "_mshr_miss_rate") 540 .desc("mshr miss rate for " + cstr + " accesses") 541 .flags(total | nozero | nonan) 542 ; 543 544 mshrMissRate[access_idx] = 545 mshr_misses[access_idx] / accesses[access_idx]; 546 } 547 548 demandMshrMissRate 549 .name(name() + ".demand_mshr_miss_rate") 550 .desc("mshr miss rate for demand accesses") 551 .flags(total) 552 ; 553 demandMshrMissRate = demandMshrMisses / demandAccesses; 554 555 overallMshrMissRate 556 .name(name() + ".overall_mshr_miss_rate") 557 .desc("mshr miss rate for overall accesses") 558 .flags(total) 559 ; 560 overallMshrMissRate = overallMshrMisses / overallAccesses; 561 562 // mshrMiss latency formulas 563 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 564 MemCmd cmd(access_idx); 565 const string &cstr = cmd.toString(); 566 567 avgMshrMissLatency[access_idx] 568 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 569 .desc("average " + cstr + " mshr miss latency") 570 .flags(total | nozero | nonan) 571 ; 572 573 avgMshrMissLatency[access_idx] = 574 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 575 } 576 577 demandAvgMshrMissLatency 578 .name(name() + ".demand_avg_mshr_miss_latency") 579 .desc("average overall mshr miss latency") 580 .flags(total) 581 ; 582 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 583 584 overallAvgMshrMissLatency 585 .name(name() + ".overall_avg_mshr_miss_latency") 586 .desc("average overall mshr miss latency") 587 .flags(total) 588 ; 589 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 590 591 // mshrUncacheable latency formulas 592 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 593 MemCmd cmd(access_idx); 594 const string &cstr = cmd.toString(); 595 596 avgMshrUncacheableLatency[access_idx] 597 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 598 .desc("average " + cstr + " mshr uncacheable latency") 599 .flags(total | nozero | nonan) 600 ; 601 602 avgMshrUncacheableLatency[access_idx] = 603 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 604 } 605 606 overallAvgMshrUncacheableLatency 607 .name(name() + ".overall_avg_mshr_uncacheable_latency") 608 .desc("average overall mshr uncacheable latency") 609 .flags(total) 610 ; 611 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 612 613 mshr_cap_events 614 .init(maxThreadsPerCPU) 615 .name(name() + ".mshr_cap_events") 616 .desc("number of times MSHR cap was activated") 617 .flags(total) 618 ; 619 620 //software prefetching stats 621 soft_prefetch_mshr_full 622 .init(maxThreadsPerCPU) 623 .name(name() + ".soft_prefetch_mshr_full") 624 .desc("number of mshr full events for SW prefetching instrutions") 625 .flags(total) 626 ; 627 628 mshr_no_allocate_misses 629 .name(name() +".no_allocate_misses") 630 .desc("Number of misses that were no-allocate") 631 ; 632 633} 634 635unsigned int 636BaseCache::drain(Event *de) 637{ 638 int count = memSidePort->drain(de) + cpuSidePort->drain(de); 639 640 // Set status 641 if (count != 0) { 642 drainEvent = de; 643 644 changeState(SimObject::Draining); 645 return count; 646 } 647 648 changeState(SimObject::Drained); 649 return 0; 650} 651