base.cc revision 10344:fa9ef374075f
1545SN/A/* 29814Sandreas.hansson@arm.com * Copyright (c) 2012-2013 ARM Limited 38948SN/A * All rights reserved. 48948SN/A * 58948SN/A * The license below extends only to copyright in the software and shall 68948SN/A * not be construed as granting a license to any other intellectual 78948SN/A * property including but not limited to intellectual property relating 88948SN/A * to a hardware implementation of the functionality of the software 98948SN/A * licensed hereunder. You may use the software subject to the license 108948SN/A * terms below provided that you ensure that this notice is replicated 118948SN/A * unmodified and in its entirety in all distributions of the software, 128948SN/A * modified or unmodified, in source code or in binary form. 138948SN/A * 141762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 15545SN/A * All rights reserved. 16545SN/A * 17545SN/A * Redistribution and use in source and binary forms, with or without 18545SN/A * modification, are permitted provided that the following conditions are 19545SN/A * met: redistributions of source code must retain the above copyright 20545SN/A * notice, this list of conditions and the following disclaimer; 21545SN/A * redistributions in binary form must reproduce the above copyright 22545SN/A * notice, this list of conditions and the following disclaimer in the 23545SN/A * documentation and/or other materials provided with the distribution; 24545SN/A * neither the name of the copyright holders nor the names of its 25545SN/A * contributors may be used to endorse or promote products derived from 26545SN/A * this software without specific prior written permission. 27545SN/A * 28545SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29545SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30545SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31545SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32545SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33545SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34545SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35545SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36545SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37545SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38545SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665SN/A * 402665SN/A * Authors: Erik Hallnor 412665SN/A */ 42545SN/A 43545SN/A/** 449016Sandreas.hansson@arm.com * @file 459016Sandreas.hansson@arm.com * Definition of BaseCache functions. 46545SN/A */ 479166Sandreas.hansson@arm.com 489166Sandreas.hansson@arm.com#include "debug/Cache.hh" 499016Sandreas.hansson@arm.com#include "debug/Drain.hh" 504762SN/A#include "mem/cache/tags/fa_lru.hh" 519342SAndreas.Sandberg@arm.com#include "mem/cache/tags/lru.hh" 529814Sandreas.hansson@arm.com#include "mem/cache/tags/random_repl.hh" 532565SN/A#include "mem/cache/base.hh" 5410912Sandreas.sandberg@arm.com#include "mem/cache/cache.hh" 552384SN/A#include "mem/cache/mshr.hh" 569307Sandreas.hansson@arm.com#include "sim/full_system.hh" 572784SN/A 589307Sandreas.hansson@arm.comusing namespace std; 599307Sandreas.hansson@arm.com 609307Sandreas.hansson@arm.comBaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name, 619307Sandreas.hansson@arm.com BaseCache *_cache, 629307Sandreas.hansson@arm.com const std::string &_label) 639307Sandreas.hansson@arm.com : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label), 649307Sandreas.hansson@arm.com blocked(false), mustSendRetry(false), sendRetryEvent(this) 652784SN/A{ 669307Sandreas.hansson@arm.com} 679307Sandreas.hansson@arm.com 689307Sandreas.hansson@arm.comBaseCache::BaseCache(const Params *p) 699307Sandreas.hansson@arm.com : MemObject(p), 709307Sandreas.hansson@arm.com mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs), 719307Sandreas.hansson@arm.com writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 729307Sandreas.hansson@arm.com MSHRQueue_WriteBuffer), 739307Sandreas.hansson@arm.com blkSize(p->system->cacheLineSize()), 744435SN/A hitLatency(p->hit_latency), 759166Sandreas.hansson@arm.com responseLatency(p->response_latency), 769166Sandreas.hansson@arm.com numTarget(p->tgts_per_mshr), 779166Sandreas.hansson@arm.com forwardSnoops(p->forward_snoops), 789166Sandreas.hansson@arm.com isTopLevel(p->is_top_level), 799166Sandreas.hansson@arm.com blocked(0), 809166Sandreas.hansson@arm.com noTargetMSHR(NULL), 819166Sandreas.hansson@arm.com missCount(p->max_miss_count), 829166Sandreas.hansson@arm.com addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()), 839166Sandreas.hansson@arm.com system(p->system) 849166Sandreas.hansson@arm.com{ 859166Sandreas.hansson@arm.com} 868948SN/A 879307Sandreas.hansson@arm.comvoid 889307Sandreas.hansson@arm.comBaseCache::CacheSlavePort::setBlocked() 899307Sandreas.hansson@arm.com{ 909307Sandreas.hansson@arm.com assert(!blocked); 919307Sandreas.hansson@arm.com DPRINTF(CachePort, "Cache port %s blocking new requests\n", name()); 929307Sandreas.hansson@arm.com blocked = true; 939307Sandreas.hansson@arm.com // if we already scheduled a retry in this cycle, but it has not yet 949307Sandreas.hansson@arm.com // happened, cancel it 959307Sandreas.hansson@arm.com if (sendRetryEvent.scheduled()) { 969307Sandreas.hansson@arm.com owner.deschedule(sendRetryEvent); 979307Sandreas.hansson@arm.com DPRINTF(CachePort, "Cache port %s deschedule retry\n", name()); 989307Sandreas.hansson@arm.com mustSendRetry = true; 999307Sandreas.hansson@arm.com } 1009307Sandreas.hansson@arm.com} 1019307Sandreas.hansson@arm.com 1029307Sandreas.hansson@arm.comvoid 1039307Sandreas.hansson@arm.comBaseCache::CacheSlavePort::clearBlocked() 1049307Sandreas.hansson@arm.com{ 1059307Sandreas.hansson@arm.com assert(blocked); 1069307Sandreas.hansson@arm.com DPRINTF(CachePort, "Cache port %s accepting new requests\n", name()); 1079307Sandreas.hansson@arm.com blocked = false; 1089307Sandreas.hansson@arm.com if (mustSendRetry) { 1099307Sandreas.hansson@arm.com // @TODO: need to find a better time (next bus cycle?) 1109307Sandreas.hansson@arm.com owner.schedule(sendRetryEvent, curTick() + 1); 1119307Sandreas.hansson@arm.com } 1129307Sandreas.hansson@arm.com} 1139307Sandreas.hansson@arm.com 1149307Sandreas.hansson@arm.comvoid 1159307Sandreas.hansson@arm.comBaseCache::CacheSlavePort::processSendRetry() 1169307Sandreas.hansson@arm.com{ 1179307Sandreas.hansson@arm.com DPRINTF(CachePort, "Cache port %s sending retry\n", name()); 1189307Sandreas.hansson@arm.com 1199307Sandreas.hansson@arm.com // reset the flag and call retry 1209307Sandreas.hansson@arm.com mustSendRetry = false; 1219307Sandreas.hansson@arm.com sendRetry(); 1229307Sandreas.hansson@arm.com} 1239307Sandreas.hansson@arm.com 1249307Sandreas.hansson@arm.comvoid 1259307Sandreas.hansson@arm.comBaseCache::init() 1269307Sandreas.hansson@arm.com{ 1279307Sandreas.hansson@arm.com if (!cpuSidePort->isConnected() || !memSidePort->isConnected()) 1289307Sandreas.hansson@arm.com fatal("Cache ports on %s are not connected\n", name()); 1299307Sandreas.hansson@arm.com cpuSidePort->sendRangeChange(); 1309307Sandreas.hansson@arm.com} 1319307Sandreas.hansson@arm.com 1329166Sandreas.hansson@arm.comBaseMasterPort & 13310713Sandreas.hansson@arm.comBaseCache::getMasterPort(const std::string &if_name, PortID idx) 1342384SN/A{ 1359166Sandreas.hansson@arm.com if (if_name == "mem_side") { 1364435SN/A return *memSidePort; 1379165Sandreas.hansson@arm.com } else { 1382489SN/A return MemObject::getMasterPort(if_name, idx); 1399165Sandreas.hansson@arm.com } 1402565SN/A} 14110621SCurtis.Dunham@arm.com 14210621SCurtis.Dunham@arm.comBaseSlavePort & 1432565SN/ABaseCache::getSlavePort(const std::string &if_name, PortID idx) 1449166Sandreas.hansson@arm.com{ 1452384SN/A if (if_name == "cpu_side") { 14610913Sandreas.sandberg@arm.com return *cpuSidePort; 1472384SN/A } else { 1482384SN/A return MemObject::getSlavePort(if_name, idx); 149545SN/A } 150545SN/A} 1514435SN/A 1528851SN/Avoid 153545SN/ABaseCache::regStats() 154545SN/A{ 1554762SN/A using namespace Stats; 1564762SN/A 1579166Sandreas.hansson@arm.com // Hit statistics 1584762SN/A for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1598851SN/A MemCmd cmd(access_idx); 1608851SN/A const string &cstr = cmd.toString(); 1614022SN/A 1628851SN/A hits[access_idx] 1634022SN/A .init(system->maxMasters()) 1642565SN/A .name(name() + "." + cstr + "_hits") 1658851SN/A .desc("number of " + cstr + " hits") 1668851SN/A .flags(total | nozero | nonan) 1674263SN/A ; 1688851SN/A for (int i = 0; i < system->maxMasters(); i++) { 1694263SN/A hits[access_idx].subname(i, system->getMasterName(i)); 1702565SN/A } 1719307Sandreas.hansson@arm.com } 1728851SN/A 1738851SN/A// These macros make it easier to sum the right subset of commands and 1742565SN/A// to change the subset of commands that are considered "demand" vs 1759814Sandreas.hansson@arm.com// "non-demand" 1764263SN/A#define SUM_DEMAND(s) \ 1779294Sandreas.hansson@arm.com (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq]) 1789294Sandreas.hansson@arm.com 1792489SN/A// should writebacks be included here? prior code was inconsistent... 180545SN/A#define SUM_NON_DEMAND(s) \ 181545SN/A (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 1829016Sandreas.hansson@arm.com 183 demandHits 184 .name(name() + ".demand_hits") 185 .desc("number of demand (read+write) hits") 186 .flags(total | nozero | nonan) 187 ; 188 demandHits = SUM_DEMAND(hits); 189 for (int i = 0; i < system->maxMasters(); i++) { 190 demandHits.subname(i, system->getMasterName(i)); 191 } 192 193 overallHits 194 .name(name() + ".overall_hits") 195 .desc("number of overall hits") 196 .flags(total | nozero | nonan) 197 ; 198 overallHits = demandHits + SUM_NON_DEMAND(hits); 199 for (int i = 0; i < system->maxMasters(); i++) { 200 overallHits.subname(i, system->getMasterName(i)); 201 } 202 203 // Miss statistics 204 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 205 MemCmd cmd(access_idx); 206 const string &cstr = cmd.toString(); 207 208 misses[access_idx] 209 .init(system->maxMasters()) 210 .name(name() + "." + cstr + "_misses") 211 .desc("number of " + cstr + " misses") 212 .flags(total | nozero | nonan) 213 ; 214 for (int i = 0; i < system->maxMasters(); i++) { 215 misses[access_idx].subname(i, system->getMasterName(i)); 216 } 217 } 218 219 demandMisses 220 .name(name() + ".demand_misses") 221 .desc("number of demand (read+write) misses") 222 .flags(total | nozero | nonan) 223 ; 224 demandMisses = SUM_DEMAND(misses); 225 for (int i = 0; i < system->maxMasters(); i++) { 226 demandMisses.subname(i, system->getMasterName(i)); 227 } 228 229 overallMisses 230 .name(name() + ".overall_misses") 231 .desc("number of overall misses") 232 .flags(total | nozero | nonan) 233 ; 234 overallMisses = demandMisses + SUM_NON_DEMAND(misses); 235 for (int i = 0; i < system->maxMasters(); i++) { 236 overallMisses.subname(i, system->getMasterName(i)); 237 } 238 239 // Miss latency statistics 240 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 241 MemCmd cmd(access_idx); 242 const string &cstr = cmd.toString(); 243 244 missLatency[access_idx] 245 .init(system->maxMasters()) 246 .name(name() + "." + cstr + "_miss_latency") 247 .desc("number of " + cstr + " miss cycles") 248 .flags(total | nozero | nonan) 249 ; 250 for (int i = 0; i < system->maxMasters(); i++) { 251 missLatency[access_idx].subname(i, system->getMasterName(i)); 252 } 253 } 254 255 demandMissLatency 256 .name(name() + ".demand_miss_latency") 257 .desc("number of demand (read+write) miss cycles") 258 .flags(total | nozero | nonan) 259 ; 260 demandMissLatency = SUM_DEMAND(missLatency); 261 for (int i = 0; i < system->maxMasters(); i++) { 262 demandMissLatency.subname(i, system->getMasterName(i)); 263 } 264 265 overallMissLatency 266 .name(name() + ".overall_miss_latency") 267 .desc("number of overall miss cycles") 268 .flags(total | nozero | nonan) 269 ; 270 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 271 for (int i = 0; i < system->maxMasters(); i++) { 272 overallMissLatency.subname(i, system->getMasterName(i)); 273 } 274 275 // access 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 accesses[access_idx] 281 .name(name() + "." + cstr + "_accesses") 282 .desc("number of " + cstr + " accesses(hits+misses)") 283 .flags(total | nozero | nonan) 284 ; 285 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 286 287 for (int i = 0; i < system->maxMasters(); i++) { 288 accesses[access_idx].subname(i, system->getMasterName(i)); 289 } 290 } 291 292 demandAccesses 293 .name(name() + ".demand_accesses") 294 .desc("number of demand (read+write) accesses") 295 .flags(total | nozero | nonan) 296 ; 297 demandAccesses = demandHits + demandMisses; 298 for (int i = 0; i < system->maxMasters(); i++) { 299 demandAccesses.subname(i, system->getMasterName(i)); 300 } 301 302 overallAccesses 303 .name(name() + ".overall_accesses") 304 .desc("number of overall (read+write) accesses") 305 .flags(total | nozero | nonan) 306 ; 307 overallAccesses = overallHits + overallMisses; 308 for (int i = 0; i < system->maxMasters(); i++) { 309 overallAccesses.subname(i, system->getMasterName(i)); 310 } 311 312 // miss rate formulas 313 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 314 MemCmd cmd(access_idx); 315 const string &cstr = cmd.toString(); 316 317 missRate[access_idx] 318 .name(name() + "." + cstr + "_miss_rate") 319 .desc("miss rate for " + cstr + " accesses") 320 .flags(total | nozero | nonan) 321 ; 322 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 323 324 for (int i = 0; i < system->maxMasters(); i++) { 325 missRate[access_idx].subname(i, system->getMasterName(i)); 326 } 327 } 328 329 demandMissRate 330 .name(name() + ".demand_miss_rate") 331 .desc("miss rate for demand accesses") 332 .flags(total | nozero | nonan) 333 ; 334 demandMissRate = demandMisses / demandAccesses; 335 for (int i = 0; i < system->maxMasters(); i++) { 336 demandMissRate.subname(i, system->getMasterName(i)); 337 } 338 339 overallMissRate 340 .name(name() + ".overall_miss_rate") 341 .desc("miss rate for overall accesses") 342 .flags(total | nozero | nonan) 343 ; 344 overallMissRate = overallMisses / overallAccesses; 345 for (int i = 0; i < system->maxMasters(); i++) { 346 overallMissRate.subname(i, system->getMasterName(i)); 347 } 348 349 // miss latency formulas 350 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 351 MemCmd cmd(access_idx); 352 const string &cstr = cmd.toString(); 353 354 avgMissLatency[access_idx] 355 .name(name() + "." + cstr + "_avg_miss_latency") 356 .desc("average " + cstr + " miss latency") 357 .flags(total | nozero | nonan) 358 ; 359 avgMissLatency[access_idx] = 360 missLatency[access_idx] / misses[access_idx]; 361 362 for (int i = 0; i < system->maxMasters(); i++) { 363 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 364 } 365 } 366 367 demandAvgMissLatency 368 .name(name() + ".demand_avg_miss_latency") 369 .desc("average overall miss latency") 370 .flags(total | nozero | nonan) 371 ; 372 demandAvgMissLatency = demandMissLatency / demandMisses; 373 for (int i = 0; i < system->maxMasters(); i++) { 374 demandAvgMissLatency.subname(i, system->getMasterName(i)); 375 } 376 377 overallAvgMissLatency 378 .name(name() + ".overall_avg_miss_latency") 379 .desc("average overall miss latency") 380 .flags(total | nozero | nonan) 381 ; 382 overallAvgMissLatency = overallMissLatency / overallMisses; 383 for (int i = 0; i < system->maxMasters(); i++) { 384 overallAvgMissLatency.subname(i, system->getMasterName(i)); 385 } 386 387 blocked_cycles.init(NUM_BLOCKED_CAUSES); 388 blocked_cycles 389 .name(name() + ".blocked_cycles") 390 .desc("number of cycles access was blocked") 391 .subname(Blocked_NoMSHRs, "no_mshrs") 392 .subname(Blocked_NoTargets, "no_targets") 393 ; 394 395 396 blocked_causes.init(NUM_BLOCKED_CAUSES); 397 blocked_causes 398 .name(name() + ".blocked") 399 .desc("number of cycles access was blocked") 400 .subname(Blocked_NoMSHRs, "no_mshrs") 401 .subname(Blocked_NoTargets, "no_targets") 402 ; 403 404 avg_blocked 405 .name(name() + ".avg_blocked_cycles") 406 .desc("average number of cycles each access was blocked") 407 .subname(Blocked_NoMSHRs, "no_mshrs") 408 .subname(Blocked_NoTargets, "no_targets") 409 ; 410 411 avg_blocked = blocked_cycles / blocked_causes; 412 413 fastWrites 414 .name(name() + ".fast_writes") 415 .desc("number of fast writes performed") 416 ; 417 418 cacheCopies 419 .name(name() + ".cache_copies") 420 .desc("number of cache copies performed") 421 ; 422 423 writebacks 424 .init(system->maxMasters()) 425 .name(name() + ".writebacks") 426 .desc("number of writebacks") 427 .flags(total | nozero | nonan) 428 ; 429 for (int i = 0; i < system->maxMasters(); i++) { 430 writebacks.subname(i, system->getMasterName(i)); 431 } 432 433 // MSHR statistics 434 // MSHR hit statistics 435 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 436 MemCmd cmd(access_idx); 437 const string &cstr = cmd.toString(); 438 439 mshr_hits[access_idx] 440 .init(system->maxMasters()) 441 .name(name() + "." + cstr + "_mshr_hits") 442 .desc("number of " + cstr + " MSHR hits") 443 .flags(total | nozero | nonan) 444 ; 445 for (int i = 0; i < system->maxMasters(); i++) { 446 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 447 } 448 } 449 450 demandMshrHits 451 .name(name() + ".demand_mshr_hits") 452 .desc("number of demand (read+write) MSHR hits") 453 .flags(total | nozero | nonan) 454 ; 455 demandMshrHits = SUM_DEMAND(mshr_hits); 456 for (int i = 0; i < system->maxMasters(); i++) { 457 demandMshrHits.subname(i, system->getMasterName(i)); 458 } 459 460 overallMshrHits 461 .name(name() + ".overall_mshr_hits") 462 .desc("number of overall MSHR hits") 463 .flags(total | nozero | nonan) 464 ; 465 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 466 for (int i = 0; i < system->maxMasters(); i++) { 467 overallMshrHits.subname(i, system->getMasterName(i)); 468 } 469 470 // MSHR miss 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_misses[access_idx] 476 .init(system->maxMasters()) 477 .name(name() + "." + cstr + "_mshr_misses") 478 .desc("number of " + cstr + " MSHR misses") 479 .flags(total | nozero | nonan) 480 ; 481 for (int i = 0; i < system->maxMasters(); i++) { 482 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 483 } 484 } 485 486 demandMshrMisses 487 .name(name() + ".demand_mshr_misses") 488 .desc("number of demand (read+write) MSHR misses") 489 .flags(total | nozero | nonan) 490 ; 491 demandMshrMisses = SUM_DEMAND(mshr_misses); 492 for (int i = 0; i < system->maxMasters(); i++) { 493 demandMshrMisses.subname(i, system->getMasterName(i)); 494 } 495 496 overallMshrMisses 497 .name(name() + ".overall_mshr_misses") 498 .desc("number of overall MSHR misses") 499 .flags(total | nozero | nonan) 500 ; 501 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 502 for (int i = 0; i < system->maxMasters(); i++) { 503 overallMshrMisses.subname(i, system->getMasterName(i)); 504 } 505 506 // MSHR miss latency statistics 507 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 508 MemCmd cmd(access_idx); 509 const string &cstr = cmd.toString(); 510 511 mshr_miss_latency[access_idx] 512 .init(system->maxMasters()) 513 .name(name() + "." + cstr + "_mshr_miss_latency") 514 .desc("number of " + cstr + " MSHR miss cycles") 515 .flags(total | nozero | nonan) 516 ; 517 for (int i = 0; i < system->maxMasters(); i++) { 518 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 519 } 520 } 521 522 demandMshrMissLatency 523 .name(name() + ".demand_mshr_miss_latency") 524 .desc("number of demand (read+write) MSHR miss cycles") 525 .flags(total | nozero | nonan) 526 ; 527 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 528 for (int i = 0; i < system->maxMasters(); i++) { 529 demandMshrMissLatency.subname(i, system->getMasterName(i)); 530 } 531 532 overallMshrMissLatency 533 .name(name() + ".overall_mshr_miss_latency") 534 .desc("number of overall MSHR miss cycles") 535 .flags(total | nozero | nonan) 536 ; 537 overallMshrMissLatency = 538 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 539 for (int i = 0; i < system->maxMasters(); i++) { 540 overallMshrMissLatency.subname(i, system->getMasterName(i)); 541 } 542 543 // MSHR uncacheable statistics 544 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 545 MemCmd cmd(access_idx); 546 const string &cstr = cmd.toString(); 547 548 mshr_uncacheable[access_idx] 549 .init(system->maxMasters()) 550 .name(name() + "." + cstr + "_mshr_uncacheable") 551 .desc("number of " + cstr + " MSHR uncacheable") 552 .flags(total | nozero | nonan) 553 ; 554 for (int i = 0; i < system->maxMasters(); i++) { 555 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 556 } 557 } 558 559 overallMshrUncacheable 560 .name(name() + ".overall_mshr_uncacheable_misses") 561 .desc("number of overall MSHR uncacheable misses") 562 .flags(total | nozero | nonan) 563 ; 564 overallMshrUncacheable = 565 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 566 for (int i = 0; i < system->maxMasters(); i++) { 567 overallMshrUncacheable.subname(i, system->getMasterName(i)); 568 } 569 570 // MSHR miss latency statistics 571 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 572 MemCmd cmd(access_idx); 573 const string &cstr = cmd.toString(); 574 575 mshr_uncacheable_lat[access_idx] 576 .init(system->maxMasters()) 577 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 578 .desc("number of " + cstr + " MSHR uncacheable cycles") 579 .flags(total | nozero | nonan) 580 ; 581 for (int i = 0; i < system->maxMasters(); i++) { 582 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i)); 583 } 584 } 585 586 overallMshrUncacheableLatency 587 .name(name() + ".overall_mshr_uncacheable_latency") 588 .desc("number of overall MSHR uncacheable cycles") 589 .flags(total | nozero | nonan) 590 ; 591 overallMshrUncacheableLatency = 592 SUM_DEMAND(mshr_uncacheable_lat) + 593 SUM_NON_DEMAND(mshr_uncacheable_lat); 594 for (int i = 0; i < system->maxMasters(); i++) { 595 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 596 } 597 598#if 0 599 // MSHR access formulas 600 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 601 MemCmd cmd(access_idx); 602 const string &cstr = cmd.toString(); 603 604 mshrAccesses[access_idx] 605 .name(name() + "." + cstr + "_mshr_accesses") 606 .desc("number of " + cstr + " mshr accesses(hits+misses)") 607 .flags(total | nozero | nonan) 608 ; 609 mshrAccesses[access_idx] = 610 mshr_hits[access_idx] + mshr_misses[access_idx] 611 + mshr_uncacheable[access_idx]; 612 } 613 614 demandMshrAccesses 615 .name(name() + ".demand_mshr_accesses") 616 .desc("number of demand (read+write) mshr accesses") 617 .flags(total | nozero | nonan) 618 ; 619 demandMshrAccesses = demandMshrHits + demandMshrMisses; 620 621 overallMshrAccesses 622 .name(name() + ".overall_mshr_accesses") 623 .desc("number of overall (read+write) mshr accesses") 624 .flags(total | nozero | nonan) 625 ; 626 overallMshrAccesses = overallMshrHits + overallMshrMisses 627 + overallMshrUncacheable; 628#endif 629 630 // MSHR miss rate formulas 631 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 632 MemCmd cmd(access_idx); 633 const string &cstr = cmd.toString(); 634 635 mshrMissRate[access_idx] 636 .name(name() + "." + cstr + "_mshr_miss_rate") 637 .desc("mshr miss rate for " + cstr + " accesses") 638 .flags(total | nozero | nonan) 639 ; 640 mshrMissRate[access_idx] = 641 mshr_misses[access_idx] / accesses[access_idx]; 642 643 for (int i = 0; i < system->maxMasters(); i++) { 644 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 645 } 646 } 647 648 demandMshrMissRate 649 .name(name() + ".demand_mshr_miss_rate") 650 .desc("mshr miss rate for demand accesses") 651 .flags(total | nozero | nonan) 652 ; 653 demandMshrMissRate = demandMshrMisses / demandAccesses; 654 for (int i = 0; i < system->maxMasters(); i++) { 655 demandMshrMissRate.subname(i, system->getMasterName(i)); 656 } 657 658 overallMshrMissRate 659 .name(name() + ".overall_mshr_miss_rate") 660 .desc("mshr miss rate for overall accesses") 661 .flags(total | nozero | nonan) 662 ; 663 overallMshrMissRate = overallMshrMisses / overallAccesses; 664 for (int i = 0; i < system->maxMasters(); i++) { 665 overallMshrMissRate.subname(i, system->getMasterName(i)); 666 } 667 668 // mshrMiss latency formulas 669 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 670 MemCmd cmd(access_idx); 671 const string &cstr = cmd.toString(); 672 673 avgMshrMissLatency[access_idx] 674 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 675 .desc("average " + cstr + " mshr miss latency") 676 .flags(total | nozero | nonan) 677 ; 678 avgMshrMissLatency[access_idx] = 679 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 680 681 for (int i = 0; i < system->maxMasters(); i++) { 682 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i)); 683 } 684 } 685 686 demandAvgMshrMissLatency 687 .name(name() + ".demand_avg_mshr_miss_latency") 688 .desc("average overall mshr miss latency") 689 .flags(total | nozero | nonan) 690 ; 691 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 692 for (int i = 0; i < system->maxMasters(); i++) { 693 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 694 } 695 696 overallAvgMshrMissLatency 697 .name(name() + ".overall_avg_mshr_miss_latency") 698 .desc("average overall mshr miss latency") 699 .flags(total | nozero | nonan) 700 ; 701 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 702 for (int i = 0; i < system->maxMasters(); i++) { 703 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 704 } 705 706 // mshrUncacheable latency formulas 707 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 708 MemCmd cmd(access_idx); 709 const string &cstr = cmd.toString(); 710 711 avgMshrUncacheableLatency[access_idx] 712 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 713 .desc("average " + cstr + " mshr uncacheable latency") 714 .flags(total | nozero | nonan) 715 ; 716 avgMshrUncacheableLatency[access_idx] = 717 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 718 719 for (int i = 0; i < system->maxMasters(); i++) { 720 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i)); 721 } 722 } 723 724 overallAvgMshrUncacheableLatency 725 .name(name() + ".overall_avg_mshr_uncacheable_latency") 726 .desc("average overall mshr uncacheable latency") 727 .flags(total | nozero | nonan) 728 ; 729 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 730 for (int i = 0; i < system->maxMasters(); i++) { 731 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 732 } 733 734 mshr_cap_events 735 .init(system->maxMasters()) 736 .name(name() + ".mshr_cap_events") 737 .desc("number of times MSHR cap was activated") 738 .flags(total | nozero | nonan) 739 ; 740 for (int i = 0; i < system->maxMasters(); i++) { 741 mshr_cap_events.subname(i, system->getMasterName(i)); 742 } 743 744 //software prefetching stats 745 soft_prefetch_mshr_full 746 .init(system->maxMasters()) 747 .name(name() + ".soft_prefetch_mshr_full") 748 .desc("number of mshr full events for SW prefetching instrutions") 749 .flags(total | nozero | nonan) 750 ; 751 for (int i = 0; i < system->maxMasters(); i++) { 752 soft_prefetch_mshr_full.subname(i, system->getMasterName(i)); 753 } 754 755 mshr_no_allocate_misses 756 .name(name() +".no_allocate_misses") 757 .desc("Number of misses that were no-allocate") 758 ; 759 760} 761 762unsigned int 763BaseCache::drain(DrainManager *dm) 764{ 765 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) + 766 mshrQueue.drain(dm) + writeBuffer.drain(dm); 767 768 // Set status 769 if (count != 0) { 770 setDrainState(Drainable::Draining); 771 DPRINTF(Drain, "Cache not drained\n"); 772 return count; 773 } 774 775 setDrainState(Drainable::Drained); 776 return 0; 777} 778 779BaseCache * 780BaseCacheParams::create() 781{ 782 unsigned numSets = size / (assoc * system->cacheLineSize()); 783 784 assert(tags); 785 786 if (dynamic_cast<FALRU*>(tags)) { 787 if (numSets != 1) 788 fatal("Got FALRU tags with more than one set\n"); 789 return new Cache<FALRU>(this); 790 } else if (dynamic_cast<LRU*>(tags)) { 791 if (numSets == 1) 792 warn("Consider using FALRU tags for a fully associative cache\n"); 793 return new Cache<LRU>(this); 794 } else if (dynamic_cast<RandomRepl*>(tags)) { 795 return new Cache<RandomRepl>(this); 796 } else { 797 fatal("No suitable tags selected\n"); 798 } 799} 800