base.cc revision 9263
113540Sandrea.mondelli@ucf.edu/* 210235Syasuko.eckert@amd.com * Copyright (c) 2012 ARM Limited 310235Syasuko.eckert@amd.com * All rights reserved. 410235Syasuko.eckert@amd.com * 510235Syasuko.eckert@amd.com * The license below extends only to copyright in the software and shall 610235Syasuko.eckert@amd.com * not be construed as granting a license to any other intellectual 710235Syasuko.eckert@amd.com * property including but not limited to intellectual property relating 810235Syasuko.eckert@amd.com * to a hardware implementation of the functionality of the software 910235Syasuko.eckert@amd.com * licensed hereunder. You may use the software subject to the license 1010235Syasuko.eckert@amd.com * terms below provided that you ensure that this notice is replicated 1110235Syasuko.eckert@amd.com * unmodified and in its entirety in all distributions of the software, 1210235Syasuko.eckert@amd.com * modified or unmodified, in source code or in binary form. 1310235Syasuko.eckert@amd.com * 1410235Syasuko.eckert@amd.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 1510235Syasuko.eckert@amd.com * All rights reserved. 1610235Syasuko.eckert@amd.com * 1710235Syasuko.eckert@amd.com * Redistribution and use in source and binary forms, with or without 1810235Syasuko.eckert@amd.com * modification, are permitted provided that the following conditions are 1910235Syasuko.eckert@amd.com * met: redistributions of source code must retain the above copyright 2010235Syasuko.eckert@amd.com * notice, this list of conditions and the following disclaimer; 2110235Syasuko.eckert@amd.com * redistributions in binary form must reproduce the above copyright 2210235Syasuko.eckert@amd.com * notice, this list of conditions and the following disclaimer in the 2310235Syasuko.eckert@amd.com * documentation and/or other materials provided with the distribution; 2410235Syasuko.eckert@amd.com * neither the name of the copyright holders nor the names of its 2510235Syasuko.eckert@amd.com * contributors may be used to endorse or promote products derived from 2610235Syasuko.eckert@amd.com * this software without specific prior written permission. 2710235Syasuko.eckert@amd.com * 2810235Syasuko.eckert@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2910235Syasuko.eckert@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3010235Syasuko.eckert@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3110235Syasuko.eckert@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3210235Syasuko.eckert@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3310235Syasuko.eckert@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3410235Syasuko.eckert@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3510235Syasuko.eckert@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3610235Syasuko.eckert@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3710235Syasuko.eckert@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3810235Syasuko.eckert@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3910235Syasuko.eckert@amd.com * 4010235Syasuko.eckert@amd.com * Authors: Erik Hallnor 4110235Syasuko.eckert@amd.com */ 4210235Syasuko.eckert@amd.com 4310235Syasuko.eckert@amd.com/** 4410235Syasuko.eckert@amd.com * @file 4510235Syasuko.eckert@amd.com * Definition of BaseCache functions. 4610235Syasuko.eckert@amd.com */ 4710235Syasuko.eckert@amd.com 4810235Syasuko.eckert@amd.com#include "cpu/base.hh" 4910235Syasuko.eckert@amd.com#include "cpu/smt.hh" 5010235Syasuko.eckert@amd.com#include "debug/Cache.hh" 5110235Syasuko.eckert@amd.com#include "debug/Drain.hh" 5210235Syasuko.eckert@amd.com#include "mem/cache/base.hh" 5310235Syasuko.eckert@amd.com#include "mem/cache/mshr.hh" 5410235Syasuko.eckert@amd.com#include "sim/full_system.hh" 5510235Syasuko.eckert@amd.com 5610235Syasuko.eckert@amd.comusing namespace std; 5710235Syasuko.eckert@amd.com 5810235Syasuko.eckert@amd.comBaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name, 5910235Syasuko.eckert@amd.com BaseCache *_cache, 6010235Syasuko.eckert@amd.com const std::string &_label) 6110235Syasuko.eckert@amd.com : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label), 6210235Syasuko.eckert@amd.com blocked(false), mustSendRetry(false), sendRetryEvent(this) 6310235Syasuko.eckert@amd.com{ 6410235Syasuko.eckert@amd.com} 6510235Syasuko.eckert@amd.com 6610235Syasuko.eckert@amd.comBaseCache::BaseCache(const Params *p) 6710235Syasuko.eckert@amd.com : MemObject(p), 6810235Syasuko.eckert@amd.com mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs), 6910235Syasuko.eckert@amd.com writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 7010235Syasuko.eckert@amd.com MSHRQueue_WriteBuffer), 7110235Syasuko.eckert@amd.com blkSize(p->block_size), 7210235Syasuko.eckert@amd.com hitLatency(p->hit_latency), 7310235Syasuko.eckert@amd.com responseLatency(p->response_latency), 7410235Syasuko.eckert@amd.com numTarget(p->tgts_per_mshr), 7510235Syasuko.eckert@amd.com forwardSnoops(p->forward_snoops), 7610235Syasuko.eckert@amd.com isTopLevel(p->is_top_level), 7710235Syasuko.eckert@amd.com blocked(0), 7810235Syasuko.eckert@amd.com noTargetMSHR(NULL), 7910235Syasuko.eckert@amd.com missCount(p->max_miss_count), 8010235Syasuko.eckert@amd.com drainEvent(NULL), 8110235Syasuko.eckert@amd.com addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()), 8210235Syasuko.eckert@amd.com system(p->system) 8310235Syasuko.eckert@amd.com{ 8410235Syasuko.eckert@amd.com} 8510235Syasuko.eckert@amd.com 8610235Syasuko.eckert@amd.comvoid 8710235Syasuko.eckert@amd.comBaseCache::CacheSlavePort::setBlocked() 8810235Syasuko.eckert@amd.com{ 8910235Syasuko.eckert@amd.com assert(!blocked); 9010235Syasuko.eckert@amd.com DPRINTF(CachePort, "Cache port %s blocking new requests\n", name()); 9110235Syasuko.eckert@amd.com blocked = true; 9210235Syasuko.eckert@amd.com} 9310235Syasuko.eckert@amd.com 9410235Syasuko.eckert@amd.comvoid 9510235Syasuko.eckert@amd.comBaseCache::CacheSlavePort::clearBlocked() 9610235Syasuko.eckert@amd.com{ 9710235Syasuko.eckert@amd.com assert(blocked); 9810235Syasuko.eckert@amd.com DPRINTF(CachePort, "Cache port %s accepting new requests\n", name()); 9910235Syasuko.eckert@amd.com blocked = false; 10010235Syasuko.eckert@amd.com if (mustSendRetry) { 10110235Syasuko.eckert@amd.com DPRINTF(CachePort, "Cache port %s sending retry\n", name()); 10210235Syasuko.eckert@amd.com mustSendRetry = false; 10310235Syasuko.eckert@amd.com // @TODO: need to find a better time (next bus cycle?) 10410235Syasuko.eckert@amd.com owner.schedule(sendRetryEvent, curTick() + 1); 10510235Syasuko.eckert@amd.com } 10610235Syasuko.eckert@amd.com} 10710235Syasuko.eckert@amd.com 10810235Syasuko.eckert@amd.com 10910235Syasuko.eckert@amd.comvoid 11010235Syasuko.eckert@amd.comBaseCache::init() 11110235Syasuko.eckert@amd.com{ 11210235Syasuko.eckert@amd.com if (!cpuSidePort->isConnected() || !memSidePort->isConnected()) 11310235Syasuko.eckert@amd.com fatal("Cache ports on %s are not connected\n", name()); 11410235Syasuko.eckert@amd.com cpuSidePort->sendRangeChange(); 11510235Syasuko.eckert@amd.com} 11610235Syasuko.eckert@amd.com 11710235Syasuko.eckert@amd.comMasterPort & 11810235Syasuko.eckert@amd.comBaseCache::getMasterPort(const std::string &if_name, int idx) 11910235Syasuko.eckert@amd.com{ 12010235Syasuko.eckert@amd.com if (if_name == "mem_side") { 12110235Syasuko.eckert@amd.com return *memSidePort; 12210235Syasuko.eckert@amd.com } else { 12310235Syasuko.eckert@amd.com return MemObject::getMasterPort(if_name, idx); 12410235Syasuko.eckert@amd.com } 12510235Syasuko.eckert@amd.com} 12610235Syasuko.eckert@amd.com 12710235Syasuko.eckert@amd.comSlavePort & 12810235Syasuko.eckert@amd.comBaseCache::getSlavePort(const std::string &if_name, int idx) 12910235Syasuko.eckert@amd.com{ 13010235Syasuko.eckert@amd.com if (if_name == "cpu_side") { 13110235Syasuko.eckert@amd.com return *cpuSidePort; 13210235Syasuko.eckert@amd.com } else { 13310235Syasuko.eckert@amd.com return MemObject::getSlavePort(if_name, idx); 13410235Syasuko.eckert@amd.com } 13510235Syasuko.eckert@amd.com} 13610235Syasuko.eckert@amd.com 13710235Syasuko.eckert@amd.comvoid 13810235Syasuko.eckert@amd.comBaseCache::regStats() 13910235Syasuko.eckert@amd.com{ 14010235Syasuko.eckert@amd.com using namespace Stats; 14110235Syasuko.eckert@amd.com 14210235Syasuko.eckert@amd.com // Hit statistics 14310235Syasuko.eckert@amd.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 14410235Syasuko.eckert@amd.com MemCmd cmd(access_idx); 14510235Syasuko.eckert@amd.com const string &cstr = cmd.toString(); 14610235Syasuko.eckert@amd.com 14710235Syasuko.eckert@amd.com hits[access_idx] 14810235Syasuko.eckert@amd.com .init(system->maxMasters()) 14910235Syasuko.eckert@amd.com .name(name() + "." + cstr + "_hits") 15010235Syasuko.eckert@amd.com .desc("number of " + cstr + " hits") 15110235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 15210235Syasuko.eckert@amd.com ; 15310235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 15410235Syasuko.eckert@amd.com hits[access_idx].subname(i, system->getMasterName(i)); 15510235Syasuko.eckert@amd.com } 15610235Syasuko.eckert@amd.com } 15710235Syasuko.eckert@amd.com 15810235Syasuko.eckert@amd.com// These macros make it easier to sum the right subset of commands and 15910235Syasuko.eckert@amd.com// to change the subset of commands that are considered "demand" vs 16010235Syasuko.eckert@amd.com// "non-demand" 16110235Syasuko.eckert@amd.com#define SUM_DEMAND(s) \ 16210235Syasuko.eckert@amd.com (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq]) 16310235Syasuko.eckert@amd.com 16410235Syasuko.eckert@amd.com// should writebacks be included here? prior code was inconsistent... 16510235Syasuko.eckert@amd.com#define SUM_NON_DEMAND(s) \ 16610235Syasuko.eckert@amd.com (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 16710235Syasuko.eckert@amd.com 16810235Syasuko.eckert@amd.com demandHits 16910235Syasuko.eckert@amd.com .name(name() + ".demand_hits") 17010235Syasuko.eckert@amd.com .desc("number of demand (read+write) hits") 17110235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 17210235Syasuko.eckert@amd.com ; 17310235Syasuko.eckert@amd.com demandHits = SUM_DEMAND(hits); 17410235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 17510235Syasuko.eckert@amd.com demandHits.subname(i, system->getMasterName(i)); 17610235Syasuko.eckert@amd.com } 17710235Syasuko.eckert@amd.com 17810235Syasuko.eckert@amd.com overallHits 17910235Syasuko.eckert@amd.com .name(name() + ".overall_hits") 18010235Syasuko.eckert@amd.com .desc("number of overall hits") 18110235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 18210235Syasuko.eckert@amd.com ; 18310235Syasuko.eckert@amd.com overallHits = demandHits + SUM_NON_DEMAND(hits); 18410235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 18510235Syasuko.eckert@amd.com overallHits.subname(i, system->getMasterName(i)); 18610235Syasuko.eckert@amd.com } 18710235Syasuko.eckert@amd.com 18810235Syasuko.eckert@amd.com // Miss statistics 18910235Syasuko.eckert@amd.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 19010235Syasuko.eckert@amd.com MemCmd cmd(access_idx); 19110235Syasuko.eckert@amd.com const string &cstr = cmd.toString(); 19210235Syasuko.eckert@amd.com 19310235Syasuko.eckert@amd.com misses[access_idx] 19410235Syasuko.eckert@amd.com .init(system->maxMasters()) 19510235Syasuko.eckert@amd.com .name(name() + "." + cstr + "_misses") 19610235Syasuko.eckert@amd.com .desc("number of " + cstr + " misses") 19710235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 19810235Syasuko.eckert@amd.com ; 19910235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 20010235Syasuko.eckert@amd.com misses[access_idx].subname(i, system->getMasterName(i)); 20110235Syasuko.eckert@amd.com } 20210235Syasuko.eckert@amd.com } 20310235Syasuko.eckert@amd.com 20410235Syasuko.eckert@amd.com demandMisses 20510235Syasuko.eckert@amd.com .name(name() + ".demand_misses") 20610235Syasuko.eckert@amd.com .desc("number of demand (read+write) misses") 20710235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 20810235Syasuko.eckert@amd.com ; 20910235Syasuko.eckert@amd.com demandMisses = SUM_DEMAND(misses); 21010235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 21110235Syasuko.eckert@amd.com demandMisses.subname(i, system->getMasterName(i)); 21210235Syasuko.eckert@amd.com } 21310235Syasuko.eckert@amd.com 21410235Syasuko.eckert@amd.com overallMisses 21510235Syasuko.eckert@amd.com .name(name() + ".overall_misses") 21610235Syasuko.eckert@amd.com .desc("number of overall misses") 21710235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 21810235Syasuko.eckert@amd.com ; 21910235Syasuko.eckert@amd.com overallMisses = demandMisses + SUM_NON_DEMAND(misses); 22010235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 22110235Syasuko.eckert@amd.com overallMisses.subname(i, system->getMasterName(i)); 22210235Syasuko.eckert@amd.com } 22310235Syasuko.eckert@amd.com 22410235Syasuko.eckert@amd.com // Miss latency statistics 22510235Syasuko.eckert@amd.com for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 22610235Syasuko.eckert@amd.com MemCmd cmd(access_idx); 22710235Syasuko.eckert@amd.com const string &cstr = cmd.toString(); 22810235Syasuko.eckert@amd.com 22910235Syasuko.eckert@amd.com missLatency[access_idx] 23010235Syasuko.eckert@amd.com .init(system->maxMasters()) 23110235Syasuko.eckert@amd.com .name(name() + "." + cstr + "_miss_latency") 23210235Syasuko.eckert@amd.com .desc("number of " + cstr + " miss cycles") 23310235Syasuko.eckert@amd.com .flags(total | nozero | nonan) 23410235Syasuko.eckert@amd.com ; 23510235Syasuko.eckert@amd.com for (int i = 0; i < system->maxMasters(); i++) { 23610235Syasuko.eckert@amd.com missLatency[access_idx].subname(i, system->getMasterName(i)); 23710235Syasuko.eckert@amd.com } 23810235Syasuko.eckert@amd.com } 23910235Syasuko.eckert@amd.com 24010235Syasuko.eckert@amd.com demandMissLatency 24110235Syasuko.eckert@amd.com .name(name() + ".demand_miss_latency") 242 .desc("number of demand (read+write) miss cycles") 243 .flags(total | nozero | nonan) 244 ; 245 demandMissLatency = SUM_DEMAND(missLatency); 246 for (int i = 0; i < system->maxMasters(); i++) { 247 demandMissLatency.subname(i, system->getMasterName(i)); 248 } 249 250 overallMissLatency 251 .name(name() + ".overall_miss_latency") 252 .desc("number of overall miss cycles") 253 .flags(total | nozero | nonan) 254 ; 255 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 256 for (int i = 0; i < system->maxMasters(); i++) { 257 overallMissLatency.subname(i, system->getMasterName(i)); 258 } 259 260 // access formulas 261 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 262 MemCmd cmd(access_idx); 263 const string &cstr = cmd.toString(); 264 265 accesses[access_idx] 266 .name(name() + "." + cstr + "_accesses") 267 .desc("number of " + cstr + " accesses(hits+misses)") 268 .flags(total | nozero | nonan) 269 ; 270 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 271 272 for (int i = 0; i < system->maxMasters(); i++) { 273 accesses[access_idx].subname(i, system->getMasterName(i)); 274 } 275 } 276 277 demandAccesses 278 .name(name() + ".demand_accesses") 279 .desc("number of demand (read+write) accesses") 280 .flags(total | nozero | nonan) 281 ; 282 demandAccesses = demandHits + demandMisses; 283 for (int i = 0; i < system->maxMasters(); i++) { 284 demandAccesses.subname(i, system->getMasterName(i)); 285 } 286 287 overallAccesses 288 .name(name() + ".overall_accesses") 289 .desc("number of overall (read+write) accesses") 290 .flags(total | nozero | nonan) 291 ; 292 overallAccesses = overallHits + overallMisses; 293 for (int i = 0; i < system->maxMasters(); i++) { 294 overallAccesses.subname(i, system->getMasterName(i)); 295 } 296 297 // miss rate formulas 298 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 299 MemCmd cmd(access_idx); 300 const string &cstr = cmd.toString(); 301 302 missRate[access_idx] 303 .name(name() + "." + cstr + "_miss_rate") 304 .desc("miss rate for " + cstr + " accesses") 305 .flags(total | nozero | nonan) 306 ; 307 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 308 309 for (int i = 0; i < system->maxMasters(); i++) { 310 missRate[access_idx].subname(i, system->getMasterName(i)); 311 } 312 } 313 314 demandMissRate 315 .name(name() + ".demand_miss_rate") 316 .desc("miss rate for demand accesses") 317 .flags(total | nozero | nonan) 318 ; 319 demandMissRate = demandMisses / demandAccesses; 320 for (int i = 0; i < system->maxMasters(); i++) { 321 demandMissRate.subname(i, system->getMasterName(i)); 322 } 323 324 overallMissRate 325 .name(name() + ".overall_miss_rate") 326 .desc("miss rate for overall accesses") 327 .flags(total | nozero | nonan) 328 ; 329 overallMissRate = overallMisses / overallAccesses; 330 for (int i = 0; i < system->maxMasters(); i++) { 331 overallMissRate.subname(i, system->getMasterName(i)); 332 } 333 334 // miss latency formulas 335 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 336 MemCmd cmd(access_idx); 337 const string &cstr = cmd.toString(); 338 339 avgMissLatency[access_idx] 340 .name(name() + "." + cstr + "_avg_miss_latency") 341 .desc("average " + cstr + " miss latency") 342 .flags(total | nozero | nonan) 343 ; 344 avgMissLatency[access_idx] = 345 missLatency[access_idx] / misses[access_idx]; 346 347 for (int i = 0; i < system->maxMasters(); i++) { 348 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 349 } 350 } 351 352 demandAvgMissLatency 353 .name(name() + ".demand_avg_miss_latency") 354 .desc("average overall miss latency") 355 .flags(total | nozero | nonan) 356 ; 357 demandAvgMissLatency = demandMissLatency / demandMisses; 358 for (int i = 0; i < system->maxMasters(); i++) { 359 demandAvgMissLatency.subname(i, system->getMasterName(i)); 360 } 361 362 overallAvgMissLatency 363 .name(name() + ".overall_avg_miss_latency") 364 .desc("average overall miss latency") 365 .flags(total | nozero | nonan) 366 ; 367 overallAvgMissLatency = overallMissLatency / overallMisses; 368 for (int i = 0; i < system->maxMasters(); i++) { 369 overallAvgMissLatency.subname(i, system->getMasterName(i)); 370 } 371 372 blocked_cycles.init(NUM_BLOCKED_CAUSES); 373 blocked_cycles 374 .name(name() + ".blocked_cycles") 375 .desc("number of cycles access was blocked") 376 .subname(Blocked_NoMSHRs, "no_mshrs") 377 .subname(Blocked_NoTargets, "no_targets") 378 ; 379 380 381 blocked_causes.init(NUM_BLOCKED_CAUSES); 382 blocked_causes 383 .name(name() + ".blocked") 384 .desc("number of cycles access was blocked") 385 .subname(Blocked_NoMSHRs, "no_mshrs") 386 .subname(Blocked_NoTargets, "no_targets") 387 ; 388 389 avg_blocked 390 .name(name() + ".avg_blocked_cycles") 391 .desc("average number of cycles each access was blocked") 392 .subname(Blocked_NoMSHRs, "no_mshrs") 393 .subname(Blocked_NoTargets, "no_targets") 394 ; 395 396 avg_blocked = blocked_cycles / blocked_causes; 397 398 fastWrites 399 .name(name() + ".fast_writes") 400 .desc("number of fast writes performed") 401 ; 402 403 cacheCopies 404 .name(name() + ".cache_copies") 405 .desc("number of cache copies performed") 406 ; 407 408 writebacks 409 .init(system->maxMasters()) 410 .name(name() + ".writebacks") 411 .desc("number of writebacks") 412 .flags(total | nozero | nonan) 413 ; 414 for (int i = 0; i < system->maxMasters(); i++) { 415 writebacks.subname(i, system->getMasterName(i)); 416 } 417 418 // MSHR statistics 419 // MSHR hit statistics 420 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 421 MemCmd cmd(access_idx); 422 const string &cstr = cmd.toString(); 423 424 mshr_hits[access_idx] 425 .init(system->maxMasters()) 426 .name(name() + "." + cstr + "_mshr_hits") 427 .desc("number of " + cstr + " MSHR hits") 428 .flags(total | nozero | nonan) 429 ; 430 for (int i = 0; i < system->maxMasters(); i++) { 431 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 432 } 433 } 434 435 demandMshrHits 436 .name(name() + ".demand_mshr_hits") 437 .desc("number of demand (read+write) MSHR hits") 438 .flags(total | nozero | nonan) 439 ; 440 demandMshrHits = SUM_DEMAND(mshr_hits); 441 for (int i = 0; i < system->maxMasters(); i++) { 442 demandMshrHits.subname(i, system->getMasterName(i)); 443 } 444 445 overallMshrHits 446 .name(name() + ".overall_mshr_hits") 447 .desc("number of overall MSHR hits") 448 .flags(total | nozero | nonan) 449 ; 450 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 451 for (int i = 0; i < system->maxMasters(); i++) { 452 overallMshrHits.subname(i, system->getMasterName(i)); 453 } 454 455 // MSHR miss statistics 456 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 457 MemCmd cmd(access_idx); 458 const string &cstr = cmd.toString(); 459 460 mshr_misses[access_idx] 461 .init(system->maxMasters()) 462 .name(name() + "." + cstr + "_mshr_misses") 463 .desc("number of " + cstr + " MSHR misses") 464 .flags(total | nozero | nonan) 465 ; 466 for (int i = 0; i < system->maxMasters(); i++) { 467 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 468 } 469 } 470 471 demandMshrMisses 472 .name(name() + ".demand_mshr_misses") 473 .desc("number of demand (read+write) MSHR misses") 474 .flags(total | nozero | nonan) 475 ; 476 demandMshrMisses = SUM_DEMAND(mshr_misses); 477 for (int i = 0; i < system->maxMasters(); i++) { 478 demandMshrMisses.subname(i, system->getMasterName(i)); 479 } 480 481 overallMshrMisses 482 .name(name() + ".overall_mshr_misses") 483 .desc("number of overall MSHR misses") 484 .flags(total | nozero | nonan) 485 ; 486 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 487 for (int i = 0; i < system->maxMasters(); i++) { 488 overallMshrMisses.subname(i, system->getMasterName(i)); 489 } 490 491 // MSHR miss latency statistics 492 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 493 MemCmd cmd(access_idx); 494 const string &cstr = cmd.toString(); 495 496 mshr_miss_latency[access_idx] 497 .init(system->maxMasters()) 498 .name(name() + "." + cstr + "_mshr_miss_latency") 499 .desc("number of " + cstr + " MSHR miss cycles") 500 .flags(total | nozero | nonan) 501 ; 502 for (int i = 0; i < system->maxMasters(); i++) { 503 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 504 } 505 } 506 507 demandMshrMissLatency 508 .name(name() + ".demand_mshr_miss_latency") 509 .desc("number of demand (read+write) MSHR miss cycles") 510 .flags(total | nozero | nonan) 511 ; 512 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 513 for (int i = 0; i < system->maxMasters(); i++) { 514 demandMshrMissLatency.subname(i, system->getMasterName(i)); 515 } 516 517 overallMshrMissLatency 518 .name(name() + ".overall_mshr_miss_latency") 519 .desc("number of overall MSHR miss cycles") 520 .flags(total | nozero | nonan) 521 ; 522 overallMshrMissLatency = 523 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 524 for (int i = 0; i < system->maxMasters(); i++) { 525 overallMshrMissLatency.subname(i, system->getMasterName(i)); 526 } 527 528 // MSHR uncacheable statistics 529 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 530 MemCmd cmd(access_idx); 531 const string &cstr = cmd.toString(); 532 533 mshr_uncacheable[access_idx] 534 .init(system->maxMasters()) 535 .name(name() + "." + cstr + "_mshr_uncacheable") 536 .desc("number of " + cstr + " MSHR uncacheable") 537 .flags(total | nozero | nonan) 538 ; 539 for (int i = 0; i < system->maxMasters(); i++) { 540 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 541 } 542 } 543 544 overallMshrUncacheable 545 .name(name() + ".overall_mshr_uncacheable_misses") 546 .desc("number of overall MSHR uncacheable misses") 547 .flags(total | nozero | nonan) 548 ; 549 overallMshrUncacheable = 550 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 551 for (int i = 0; i < system->maxMasters(); i++) { 552 overallMshrUncacheable.subname(i, system->getMasterName(i)); 553 } 554 555 // MSHR miss latency statistics 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 mshr_uncacheable_lat[access_idx] 561 .init(system->maxMasters()) 562 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 563 .desc("number of " + cstr + " MSHR uncacheable cycles") 564 .flags(total | nozero | nonan) 565 ; 566 for (int i = 0; i < system->maxMasters(); i++) { 567 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i)); 568 } 569 } 570 571 overallMshrUncacheableLatency 572 .name(name() + ".overall_mshr_uncacheable_latency") 573 .desc("number of overall MSHR uncacheable cycles") 574 .flags(total | nozero | nonan) 575 ; 576 overallMshrUncacheableLatency = 577 SUM_DEMAND(mshr_uncacheable_lat) + 578 SUM_NON_DEMAND(mshr_uncacheable_lat); 579 for (int i = 0; i < system->maxMasters(); i++) { 580 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 581 } 582 583#if 0 584 // MSHR access 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 mshrAccesses[access_idx] 590 .name(name() + "." + cstr + "_mshr_accesses") 591 .desc("number of " + cstr + " mshr accesses(hits+misses)") 592 .flags(total | nozero | nonan) 593 ; 594 mshrAccesses[access_idx] = 595 mshr_hits[access_idx] + mshr_misses[access_idx] 596 + mshr_uncacheable[access_idx]; 597 } 598 599 demandMshrAccesses 600 .name(name() + ".demand_mshr_accesses") 601 .desc("number of demand (read+write) mshr accesses") 602 .flags(total | nozero | nonan) 603 ; 604 demandMshrAccesses = demandMshrHits + demandMshrMisses; 605 606 overallMshrAccesses 607 .name(name() + ".overall_mshr_accesses") 608 .desc("number of overall (read+write) mshr accesses") 609 .flags(total | nozero | nonan) 610 ; 611 overallMshrAccesses = overallMshrHits + overallMshrMisses 612 + overallMshrUncacheable; 613#endif 614 615 // MSHR miss rate formulas 616 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 617 MemCmd cmd(access_idx); 618 const string &cstr = cmd.toString(); 619 620 mshrMissRate[access_idx] 621 .name(name() + "." + cstr + "_mshr_miss_rate") 622 .desc("mshr miss rate for " + cstr + " accesses") 623 .flags(total | nozero | nonan) 624 ; 625 mshrMissRate[access_idx] = 626 mshr_misses[access_idx] / accesses[access_idx]; 627 628 for (int i = 0; i < system->maxMasters(); i++) { 629 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 630 } 631 } 632 633 demandMshrMissRate 634 .name(name() + ".demand_mshr_miss_rate") 635 .desc("mshr miss rate for demand accesses") 636 .flags(total | nozero | nonan) 637 ; 638 demandMshrMissRate = demandMshrMisses / demandAccesses; 639 for (int i = 0; i < system->maxMasters(); i++) { 640 demandMshrMissRate.subname(i, system->getMasterName(i)); 641 } 642 643 overallMshrMissRate 644 .name(name() + ".overall_mshr_miss_rate") 645 .desc("mshr miss rate for overall accesses") 646 .flags(total | nozero | nonan) 647 ; 648 overallMshrMissRate = overallMshrMisses / overallAccesses; 649 for (int i = 0; i < system->maxMasters(); i++) { 650 overallMshrMissRate.subname(i, system->getMasterName(i)); 651 } 652 653 // mshrMiss latency formulas 654 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 655 MemCmd cmd(access_idx); 656 const string &cstr = cmd.toString(); 657 658 avgMshrMissLatency[access_idx] 659 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 660 .desc("average " + cstr + " mshr miss latency") 661 .flags(total | nozero | nonan) 662 ; 663 avgMshrMissLatency[access_idx] = 664 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 665 666 for (int i = 0; i < system->maxMasters(); i++) { 667 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i)); 668 } 669 } 670 671 demandAvgMshrMissLatency 672 .name(name() + ".demand_avg_mshr_miss_latency") 673 .desc("average overall mshr miss latency") 674 .flags(total | nozero | nonan) 675 ; 676 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 677 for (int i = 0; i < system->maxMasters(); i++) { 678 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 679 } 680 681 overallAvgMshrMissLatency 682 .name(name() + ".overall_avg_mshr_miss_latency") 683 .desc("average overall mshr miss latency") 684 .flags(total | nozero | nonan) 685 ; 686 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 687 for (int i = 0; i < system->maxMasters(); i++) { 688 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 689 } 690 691 // mshrUncacheable latency formulas 692 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 693 MemCmd cmd(access_idx); 694 const string &cstr = cmd.toString(); 695 696 avgMshrUncacheableLatency[access_idx] 697 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 698 .desc("average " + cstr + " mshr uncacheable latency") 699 .flags(total | nozero | nonan) 700 ; 701 avgMshrUncacheableLatency[access_idx] = 702 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 703 704 for (int i = 0; i < system->maxMasters(); i++) { 705 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i)); 706 } 707 } 708 709 overallAvgMshrUncacheableLatency 710 .name(name() + ".overall_avg_mshr_uncacheable_latency") 711 .desc("average overall mshr uncacheable latency") 712 .flags(total | nozero | nonan) 713 ; 714 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 715 for (int i = 0; i < system->maxMasters(); i++) { 716 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 717 } 718 719 mshr_cap_events 720 .init(system->maxMasters()) 721 .name(name() + ".mshr_cap_events") 722 .desc("number of times MSHR cap was activated") 723 .flags(total | nozero | nonan) 724 ; 725 for (int i = 0; i < system->maxMasters(); i++) { 726 mshr_cap_events.subname(i, system->getMasterName(i)); 727 } 728 729 //software prefetching stats 730 soft_prefetch_mshr_full 731 .init(system->maxMasters()) 732 .name(name() + ".soft_prefetch_mshr_full") 733 .desc("number of mshr full events for SW prefetching instrutions") 734 .flags(total | nozero | nonan) 735 ; 736 for (int i = 0; i < system->maxMasters(); i++) { 737 soft_prefetch_mshr_full.subname(i, system->getMasterName(i)); 738 } 739 740 mshr_no_allocate_misses 741 .name(name() +".no_allocate_misses") 742 .desc("Number of misses that were no-allocate") 743 ; 744 745} 746 747unsigned int 748BaseCache::drain(Event *de) 749{ 750 int count = memSidePort->drain(de) + cpuSidePort->drain(de); 751 752 // Set status 753 if (count != 0) { 754 drainEvent = de; 755 756 changeState(SimObject::Draining); 757 DPRINTF(Drain, "Cache not drained\n"); 758 return count; 759 } 760 761 changeState(SimObject::Drained); 762 return 0; 763} 764