base.cc revision 10714
15390SN/A/* 25390SN/A * Copyright (c) 2012-2013 ARM Limited 35390SN/A * All rights reserved. 45390SN/A * 55390SN/A * The license below extends only to copyright in the software and shall 65390SN/A * not be construed as granting a license to any other intellectual 75390SN/A * property including but not limited to intellectual property relating 85390SN/A * to a hardware implementation of the functionality of the software 95390SN/A * licensed hereunder. You may use the software subject to the license 105390SN/A * terms below provided that you ensure that this notice is replicated 115390SN/A * unmodified and in its entirety in all distributions of the software, 125390SN/A * modified or unmodified, in source code or in binary form. 135390SN/A * 145390SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 155390SN/A * All rights reserved. 165390SN/A * 175390SN/A * Redistribution and use in source and binary forms, with or without 185390SN/A * modification, are permitted provided that the following conditions are 195390SN/A * met: redistributions of source code must retain the above copyright 205390SN/A * notice, this list of conditions and the following disclaimer; 215390SN/A * redistributions in binary form must reproduce the above copyright 225390SN/A * notice, this list of conditions and the following disclaimer in the 235390SN/A * documentation and/or other materials provided with the distribution; 245390SN/A * neither the name of the copyright holders nor the names of its 255390SN/A * contributors may be used to endorse or promote products derived from 265390SN/A * this software without specific prior written permission. 275390SN/A * 285390SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 295390SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 305390SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 315631Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 328232Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 335657Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 345630Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 355698Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 365698Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 375390SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385657Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395657Sgblack@eecs.umich.edu * 405827Sgblack@eecs.umich.edu * Authors: Erik Hallnor 415657Sgblack@eecs.umich.edu */ 425688Sgblack@eecs.umich.edu 435657Sgblack@eecs.umich.edu/** 445827Sgblack@eecs.umich.edu * @file 455827Sgblack@eecs.umich.edu * Definition of BaseCache functions. 465657Sgblack@eecs.umich.edu */ 475657Sgblack@eecs.umich.edu 485657Sgblack@eecs.umich.edu#include "debug/Cache.hh" 495390SN/A#include "debug/Drain.hh" 505390SN/A#include "mem/cache/tags/fa_lru.hh" 515390SN/A#include "mem/cache/tags/lru.hh" 525631Sgblack@eecs.umich.edu#include "mem/cache/tags/random_repl.hh" 535631Sgblack@eecs.umich.edu#include "mem/cache/base.hh" 545631Sgblack@eecs.umich.edu#include "mem/cache/cache.hh" 555631Sgblack@eecs.umich.edu#include "mem/cache/mshr.hh" 565631Sgblack@eecs.umich.edu#include "sim/full_system.hh" 575631Sgblack@eecs.umich.edu 585631Sgblack@eecs.umich.eduusing namespace std; 595631Sgblack@eecs.umich.edu 605631Sgblack@eecs.umich.eduBaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name, 615631Sgblack@eecs.umich.edu BaseCache *_cache, 625631Sgblack@eecs.umich.edu const std::string &_label) 635631Sgblack@eecs.umich.edu : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label), 645631Sgblack@eecs.umich.edu blocked(false), mustSendRetry(false), sendRetryEvent(this) 655631Sgblack@eecs.umich.edu{ 665631Sgblack@eecs.umich.edu} 675631Sgblack@eecs.umich.edu 685631Sgblack@eecs.umich.eduBaseCache::BaseCache(const Params *p) 695898Sgblack@eecs.umich.edu : MemObject(p), 705630Sgblack@eecs.umich.edu cpuSidePort(nullptr), memSidePort(nullptr), 715390SN/A mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve, MSHRQueue_MSHRs), 725390SN/A writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 0, 735390SN/A MSHRQueue_WriteBuffer), 745390SN/A blkSize(p->system->cacheLineSize()), 755390SN/A lookupLatency(p->hit_latency), 765631Sgblack@eecs.umich.edu forwardLatency(p->hit_latency), 775631Sgblack@eecs.umich.edu fillLatency(p->response_latency), 785631Sgblack@eecs.umich.edu responseLatency(p->response_latency), 795631Sgblack@eecs.umich.edu numTarget(p->tgts_per_mshr), 805631Sgblack@eecs.umich.edu forwardSnoops(p->forward_snoops), 815631Sgblack@eecs.umich.edu isTopLevel(p->is_top_level), 825631Sgblack@eecs.umich.edu blocked(0), 835631Sgblack@eecs.umich.edu order(0), 845631Sgblack@eecs.umich.edu noTargetMSHR(NULL), 855631Sgblack@eecs.umich.edu missCount(p->max_miss_count), 865631Sgblack@eecs.umich.edu addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()), 875631Sgblack@eecs.umich.edu system(p->system) 885631Sgblack@eecs.umich.edu{ 895631Sgblack@eecs.umich.edu} 905688Sgblack@eecs.umich.edu 915688Sgblack@eecs.umich.eduvoid 925688Sgblack@eecs.umich.eduBaseCache::CacheSlavePort::setBlocked() 935631Sgblack@eecs.umich.edu{ 945631Sgblack@eecs.umich.edu assert(!blocked); 955631Sgblack@eecs.umich.edu DPRINTF(CachePort, "Port is blocking new requests\n"); 965631Sgblack@eecs.umich.edu blocked = true; 975631Sgblack@eecs.umich.edu // if we already scheduled a retry in this cycle, but it has not yet 985631Sgblack@eecs.umich.edu // happened, cancel it 995631Sgblack@eecs.umich.edu if (sendRetryEvent.scheduled()) { 1005631Sgblack@eecs.umich.edu owner.deschedule(sendRetryEvent); 1015631Sgblack@eecs.umich.edu DPRINTF(CachePort, "Port descheduled retry\n"); 1025631Sgblack@eecs.umich.edu mustSendRetry = true; 1035687Sgblack@eecs.umich.edu } 1045687Sgblack@eecs.umich.edu} 1055687Sgblack@eecs.umich.edu 1065687Sgblack@eecs.umich.eduvoid 1075687Sgblack@eecs.umich.eduBaseCache::CacheSlavePort::clearBlocked() 1085687Sgblack@eecs.umich.edu{ 1095631Sgblack@eecs.umich.edu assert(blocked); 1105631Sgblack@eecs.umich.edu DPRINTF(CachePort, "Port is accepting new requests\n"); 1115631Sgblack@eecs.umich.edu blocked = false; 1125631Sgblack@eecs.umich.edu if (mustSendRetry) { 1135631Sgblack@eecs.umich.edu // @TODO: need to find a better time (next cycle?) 1145686Sgblack@eecs.umich.edu owner.schedule(sendRetryEvent, curTick() + 1); 1155686Sgblack@eecs.umich.edu } 1165686Sgblack@eecs.umich.edu} 1175686Sgblack@eecs.umich.edu 1185686Sgblack@eecs.umich.eduvoid 1195686Sgblack@eecs.umich.eduBaseCache::CacheSlavePort::processSendRetry() 1205631Sgblack@eecs.umich.edu{ 1215631Sgblack@eecs.umich.edu DPRINTF(CachePort, "Port is sending retry\n"); 1225631Sgblack@eecs.umich.edu 1235631Sgblack@eecs.umich.edu // reset the flag and call retry 1245631Sgblack@eecs.umich.edu mustSendRetry = false; 1255631Sgblack@eecs.umich.edu sendRetryReq(); 1265631Sgblack@eecs.umich.edu} 1275631Sgblack@eecs.umich.edu 1285631Sgblack@eecs.umich.eduvoid 1295631Sgblack@eecs.umich.eduBaseCache::init() 1305631Sgblack@eecs.umich.edu{ 1315631Sgblack@eecs.umich.edu if (!cpuSidePort->isConnected() || !memSidePort->isConnected()) 1325631Sgblack@eecs.umich.edu fatal("Cache ports on %s are not connected\n", name()); 1335631Sgblack@eecs.umich.edu cpuSidePort->sendRangeChange(); 1345631Sgblack@eecs.umich.edu} 1355631Sgblack@eecs.umich.edu 1365631Sgblack@eecs.umich.eduBaseMasterPort & 1375631Sgblack@eecs.umich.eduBaseCache::getMasterPort(const std::string &if_name, PortID idx) 1385631Sgblack@eecs.umich.edu{ 1395631Sgblack@eecs.umich.edu if (if_name == "mem_side") { 1405631Sgblack@eecs.umich.edu return *memSidePort; 1415631Sgblack@eecs.umich.edu } else { 1425631Sgblack@eecs.umich.edu return MemObject::getMasterPort(if_name, idx); 1435631Sgblack@eecs.umich.edu } 1445631Sgblack@eecs.umich.edu} 1455631Sgblack@eecs.umich.edu 1465631Sgblack@eecs.umich.eduBaseSlavePort & 1475631Sgblack@eecs.umich.eduBaseCache::getSlavePort(const std::string &if_name, PortID idx) 1485631Sgblack@eecs.umich.edu{ 1495631Sgblack@eecs.umich.edu if (if_name == "cpu_side") { 1505631Sgblack@eecs.umich.edu return *cpuSidePort; 1515631Sgblack@eecs.umich.edu } else { 1525631Sgblack@eecs.umich.edu return MemObject::getSlavePort(if_name, idx); 1535631Sgblack@eecs.umich.edu } 1545631Sgblack@eecs.umich.edu} 1555631Sgblack@eecs.umich.edu 1565631Sgblack@eecs.umich.eduvoid 1575631Sgblack@eecs.umich.eduBaseCache::regStats() 1585631Sgblack@eecs.umich.edu{ 1595656Sgblack@eecs.umich.edu using namespace Stats; 1605631Sgblack@eecs.umich.edu 1615656Sgblack@eecs.umich.edu // Hit statistics 1625631Sgblack@eecs.umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 1635631Sgblack@eecs.umich.edu MemCmd cmd(access_idx); 1645631Sgblack@eecs.umich.edu const string &cstr = cmd.toString(); 1655632Sgblack@eecs.umich.edu 1665631Sgblack@eecs.umich.edu hits[access_idx] 1675631Sgblack@eecs.umich.edu .init(system->maxMasters()) 1685631Sgblack@eecs.umich.edu .name(name() + "." + cstr + "_hits") 1695631Sgblack@eecs.umich.edu .desc("number of " + cstr + " hits") 1705631Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 1715634Sgblack@eecs.umich.edu ; 1725631Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 1735631Sgblack@eecs.umich.edu hits[access_idx].subname(i, system->getMasterName(i)); 1745631Sgblack@eecs.umich.edu } 1755631Sgblack@eecs.umich.edu } 1765631Sgblack@eecs.umich.edu 1775631Sgblack@eecs.umich.edu// These macros make it easier to sum the right subset of commands and 1785631Sgblack@eecs.umich.edu// to change the subset of commands that are considered "demand" vs 1795631Sgblack@eecs.umich.edu// "non-demand" 1805631Sgblack@eecs.umich.edu#define SUM_DEMAND(s) \ 1815632Sgblack@eecs.umich.edu (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq]) 1825631Sgblack@eecs.umich.edu 1835631Sgblack@eecs.umich.edu// should writebacks be included here? prior code was inconsistent... 1845632Sgblack@eecs.umich.edu#define SUM_NON_DEMAND(s) \ 1855631Sgblack@eecs.umich.edu (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq]) 1865631Sgblack@eecs.umich.edu 1875631Sgblack@eecs.umich.edu demandHits 1885631Sgblack@eecs.umich.edu .name(name() + ".demand_hits") 1895631Sgblack@eecs.umich.edu .desc("number of demand (read+write) hits") 1905631Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 1915631Sgblack@eecs.umich.edu ; 1925631Sgblack@eecs.umich.edu demandHits = SUM_DEMAND(hits); 1935631Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 1945631Sgblack@eecs.umich.edu demandHits.subname(i, system->getMasterName(i)); 1955631Sgblack@eecs.umich.edu } 1965631Sgblack@eecs.umich.edu 1975631Sgblack@eecs.umich.edu overallHits 1985631Sgblack@eecs.umich.edu .name(name() + ".overall_hits") 1995631Sgblack@eecs.umich.edu .desc("number of overall hits") 2005631Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2015631Sgblack@eecs.umich.edu ; 2025631Sgblack@eecs.umich.edu overallHits = demandHits + SUM_NON_DEMAND(hits); 2035631Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2045631Sgblack@eecs.umich.edu overallHits.subname(i, system->getMasterName(i)); 2055688Sgblack@eecs.umich.edu } 2065631Sgblack@eecs.umich.edu 2075688Sgblack@eecs.umich.edu // Miss statistics 2085688Sgblack@eecs.umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 2095631Sgblack@eecs.umich.edu MemCmd cmd(access_idx); 2105631Sgblack@eecs.umich.edu const string &cstr = cmd.toString(); 2115631Sgblack@eecs.umich.edu 2125631Sgblack@eecs.umich.edu misses[access_idx] 2135631Sgblack@eecs.umich.edu .init(system->maxMasters()) 2145631Sgblack@eecs.umich.edu .name(name() + "." + cstr + "_misses") 2155898Sgblack@eecs.umich.edu .desc("number of " + cstr + " misses") 2165630Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2175390SN/A ; 2185630Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2195632Sgblack@eecs.umich.edu misses[access_idx].subname(i, system->getMasterName(i)); 2205686Sgblack@eecs.umich.edu } 2215686Sgblack@eecs.umich.edu } 2225686Sgblack@eecs.umich.edu 2235686Sgblack@eecs.umich.edu demandMisses 2245686Sgblack@eecs.umich.edu .name(name() + ".demand_misses") 2255686Sgblack@eecs.umich.edu .desc("number of demand (read+write) misses") 2265686Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2275686Sgblack@eecs.umich.edu ; 2285686Sgblack@eecs.umich.edu demandMisses = SUM_DEMAND(misses); 2295686Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2305686Sgblack@eecs.umich.edu demandMisses.subname(i, system->getMasterName(i)); 2315686Sgblack@eecs.umich.edu } 2325686Sgblack@eecs.umich.edu 2335686Sgblack@eecs.umich.edu overallMisses 2345686Sgblack@eecs.umich.edu .name(name() + ".overall_misses") 2355827Sgblack@eecs.umich.edu .desc("number of overall misses") 2365827Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2375827Sgblack@eecs.umich.edu ; 2385686Sgblack@eecs.umich.edu overallMisses = demandMisses + SUM_NON_DEMAND(misses); 2395686Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2405686Sgblack@eecs.umich.edu overallMisses.subname(i, system->getMasterName(i)); 2415686Sgblack@eecs.umich.edu } 2425686Sgblack@eecs.umich.edu 2435686Sgblack@eecs.umich.edu // Miss latency statistics 2445686Sgblack@eecs.umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 2455686Sgblack@eecs.umich.edu MemCmd cmd(access_idx); 2465632Sgblack@eecs.umich.edu const string &cstr = cmd.toString(); 2475632Sgblack@eecs.umich.edu 2485830Sgblack@eecs.umich.edu missLatency[access_idx] 2495657Sgblack@eecs.umich.edu .init(system->maxMasters()) 2505657Sgblack@eecs.umich.edu .name(name() + "." + cstr + "_miss_latency") 2515657Sgblack@eecs.umich.edu .desc("number of " + cstr + " miss cycles") 2525632Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2535632Sgblack@eecs.umich.edu ; 2545634Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2555657Sgblack@eecs.umich.edu missLatency[access_idx].subname(i, system->getMasterName(i)); 2565686Sgblack@eecs.umich.edu } 2575632Sgblack@eecs.umich.edu } 2585632Sgblack@eecs.umich.edu 2595632Sgblack@eecs.umich.edu demandMissLatency 2605827Sgblack@eecs.umich.edu .name(name() + ".demand_miss_latency") 2615827Sgblack@eecs.umich.edu .desc("number of demand (read+write) miss cycles") 2625827Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2635830Sgblack@eecs.umich.edu ; 2645827Sgblack@eecs.umich.edu demandMissLatency = SUM_DEMAND(missLatency); 2655827Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2665827Sgblack@eecs.umich.edu demandMissLatency.subname(i, system->getMasterName(i)); 2675827Sgblack@eecs.umich.edu } 2685827Sgblack@eecs.umich.edu 2695827Sgblack@eecs.umich.edu overallMissLatency 2705827Sgblack@eecs.umich.edu .name(name() + ".overall_miss_latency") 2715827Sgblack@eecs.umich.edu .desc("number of overall miss cycles") 2725827Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2735827Sgblack@eecs.umich.edu ; 2745827Sgblack@eecs.umich.edu overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency); 2755830Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2765827Sgblack@eecs.umich.edu overallMissLatency.subname(i, system->getMasterName(i)); 2775827Sgblack@eecs.umich.edu } 2785827Sgblack@eecs.umich.edu 2795827Sgblack@eecs.umich.edu // access formulas 2805827Sgblack@eecs.umich.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 2815827Sgblack@eecs.umich.edu MemCmd cmd(access_idx); 2825657Sgblack@eecs.umich.edu const string &cstr = cmd.toString(); 2835657Sgblack@eecs.umich.edu 2845657Sgblack@eecs.umich.edu accesses[access_idx] 2855657Sgblack@eecs.umich.edu .name(name() + "." + cstr + "_accesses") 2865657Sgblack@eecs.umich.edu .desc("number of " + cstr + " accesses(hits+misses)") 2875657Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 2885657Sgblack@eecs.umich.edu ; 2895657Sgblack@eecs.umich.edu accesses[access_idx] = hits[access_idx] + misses[access_idx]; 2905657Sgblack@eecs.umich.edu 2915657Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 2925657Sgblack@eecs.umich.edu accesses[access_idx].subname(i, system->getMasterName(i)); 2935657Sgblack@eecs.umich.edu } 2945688Sgblack@eecs.umich.edu } 2955688Sgblack@eecs.umich.edu 2965688Sgblack@eecs.umich.edu demandAccesses 2975688Sgblack@eecs.umich.edu .name(name() + ".demand_accesses") 2985688Sgblack@eecs.umich.edu .desc("number of demand (read+write) accesses") 2995657Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 3005657Sgblack@eecs.umich.edu ; 3015657Sgblack@eecs.umich.edu demandAccesses = demandHits + demandMisses; 3025657Sgblack@eecs.umich.edu for (int i = 0; i < system->maxMasters(); i++) { 3035657Sgblack@eecs.umich.edu demandAccesses.subname(i, system->getMasterName(i)); 3045657Sgblack@eecs.umich.edu } 3055657Sgblack@eecs.umich.edu 3065657Sgblack@eecs.umich.edu overallAccesses 3077903Shestness@cs.utexas.edu .name(name() + ".overall_accesses") 3087903Shestness@cs.utexas.edu .desc("number of overall (read+write) accesses") 3097903Shestness@cs.utexas.edu .flags(total | nozero | nonan) 3107903Shestness@cs.utexas.edu ; 3117903Shestness@cs.utexas.edu overallAccesses = overallHits + overallMisses; 3127903Shestness@cs.utexas.edu for (int i = 0; i < system->maxMasters(); i++) { 3137903Shestness@cs.utexas.edu overallAccesses.subname(i, system->getMasterName(i)); 3147903Shestness@cs.utexas.edu } 3157903Shestness@cs.utexas.edu 3167903Shestness@cs.utexas.edu // miss rate formulas 3177903Shestness@cs.utexas.edu for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 3187903Shestness@cs.utexas.edu MemCmd cmd(access_idx); 3197903Shestness@cs.utexas.edu const string &cstr = cmd.toString(); 3207903Shestness@cs.utexas.edu 3217903Shestness@cs.utexas.edu missRate[access_idx] 3227903Shestness@cs.utexas.edu .name(name() + "." + cstr + "_miss_rate") 3237903Shestness@cs.utexas.edu .desc("miss rate for " + cstr + " accesses") 3247903Shestness@cs.utexas.edu .flags(total | nozero | nonan) 3257903Shestness@cs.utexas.edu ; 3267903Shestness@cs.utexas.edu missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 3277903Shestness@cs.utexas.edu 3287903Shestness@cs.utexas.edu for (int i = 0; i < system->maxMasters(); i++) { 3297903Shestness@cs.utexas.edu missRate[access_idx].subname(i, system->getMasterName(i)); 3307903Shestness@cs.utexas.edu } 3317903Shestness@cs.utexas.edu } 3327903Shestness@cs.utexas.edu 3337903Shestness@cs.utexas.edu demandMissRate 3347903Shestness@cs.utexas.edu .name(name() + ".demand_miss_rate") 3357903Shestness@cs.utexas.edu .desc("miss rate for demand accesses") 3367903Shestness@cs.utexas.edu .flags(total | nozero | nonan) 3377903Shestness@cs.utexas.edu ; 3387903Shestness@cs.utexas.edu demandMissRate = demandMisses / demandAccesses; 3397903Shestness@cs.utexas.edu for (int i = 0; i < system->maxMasters(); i++) { 3407903Shestness@cs.utexas.edu demandMissRate.subname(i, system->getMasterName(i)); 3417903Shestness@cs.utexas.edu } 3427903Shestness@cs.utexas.edu 3435630Sgblack@eecs.umich.edu overallMissRate 3445630Sgblack@eecs.umich.edu .name(name() + ".overall_miss_rate") 3455630Sgblack@eecs.umich.edu .desc("miss rate for overall accesses") 3465630Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 3475630Sgblack@eecs.umich.edu ; 348 overallMissRate = overallMisses / overallAccesses; 349 for (int i = 0; i < system->maxMasters(); i++) { 350 overallMissRate.subname(i, system->getMasterName(i)); 351 } 352 353 // miss latency formulas 354 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 355 MemCmd cmd(access_idx); 356 const string &cstr = cmd.toString(); 357 358 avgMissLatency[access_idx] 359 .name(name() + "." + cstr + "_avg_miss_latency") 360 .desc("average " + cstr + " miss latency") 361 .flags(total | nozero | nonan) 362 ; 363 avgMissLatency[access_idx] = 364 missLatency[access_idx] / misses[access_idx]; 365 366 for (int i = 0; i < system->maxMasters(); i++) { 367 avgMissLatency[access_idx].subname(i, system->getMasterName(i)); 368 } 369 } 370 371 demandAvgMissLatency 372 .name(name() + ".demand_avg_miss_latency") 373 .desc("average overall miss latency") 374 .flags(total | nozero | nonan) 375 ; 376 demandAvgMissLatency = demandMissLatency / demandMisses; 377 for (int i = 0; i < system->maxMasters(); i++) { 378 demandAvgMissLatency.subname(i, system->getMasterName(i)); 379 } 380 381 overallAvgMissLatency 382 .name(name() + ".overall_avg_miss_latency") 383 .desc("average overall miss latency") 384 .flags(total | nozero | nonan) 385 ; 386 overallAvgMissLatency = overallMissLatency / overallMisses; 387 for (int i = 0; i < system->maxMasters(); i++) { 388 overallAvgMissLatency.subname(i, system->getMasterName(i)); 389 } 390 391 blocked_cycles.init(NUM_BLOCKED_CAUSES); 392 blocked_cycles 393 .name(name() + ".blocked_cycles") 394 .desc("number of cycles access was blocked") 395 .subname(Blocked_NoMSHRs, "no_mshrs") 396 .subname(Blocked_NoTargets, "no_targets") 397 ; 398 399 400 blocked_causes.init(NUM_BLOCKED_CAUSES); 401 blocked_causes 402 .name(name() + ".blocked") 403 .desc("number of cycles access was blocked") 404 .subname(Blocked_NoMSHRs, "no_mshrs") 405 .subname(Blocked_NoTargets, "no_targets") 406 ; 407 408 avg_blocked 409 .name(name() + ".avg_blocked_cycles") 410 .desc("average number of cycles each access was blocked") 411 .subname(Blocked_NoMSHRs, "no_mshrs") 412 .subname(Blocked_NoTargets, "no_targets") 413 ; 414 415 avg_blocked = blocked_cycles / blocked_causes; 416 417 fastWrites 418 .name(name() + ".fast_writes") 419 .desc("number of fast writes performed") 420 ; 421 422 cacheCopies 423 .name(name() + ".cache_copies") 424 .desc("number of cache copies performed") 425 ; 426 427 writebacks 428 .init(system->maxMasters()) 429 .name(name() + ".writebacks") 430 .desc("number of writebacks") 431 .flags(total | nozero | nonan) 432 ; 433 for (int i = 0; i < system->maxMasters(); i++) { 434 writebacks.subname(i, system->getMasterName(i)); 435 } 436 437 // MSHR statistics 438 // MSHR hit statistics 439 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 440 MemCmd cmd(access_idx); 441 const string &cstr = cmd.toString(); 442 443 mshr_hits[access_idx] 444 .init(system->maxMasters()) 445 .name(name() + "." + cstr + "_mshr_hits") 446 .desc("number of " + cstr + " MSHR hits") 447 .flags(total | nozero | nonan) 448 ; 449 for (int i = 0; i < system->maxMasters(); i++) { 450 mshr_hits[access_idx].subname(i, system->getMasterName(i)); 451 } 452 } 453 454 demandMshrHits 455 .name(name() + ".demand_mshr_hits") 456 .desc("number of demand (read+write) MSHR hits") 457 .flags(total | nozero | nonan) 458 ; 459 demandMshrHits = SUM_DEMAND(mshr_hits); 460 for (int i = 0; i < system->maxMasters(); i++) { 461 demandMshrHits.subname(i, system->getMasterName(i)); 462 } 463 464 overallMshrHits 465 .name(name() + ".overall_mshr_hits") 466 .desc("number of overall MSHR hits") 467 .flags(total | nozero | nonan) 468 ; 469 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits); 470 for (int i = 0; i < system->maxMasters(); i++) { 471 overallMshrHits.subname(i, system->getMasterName(i)); 472 } 473 474 // MSHR miss statistics 475 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 476 MemCmd cmd(access_idx); 477 const string &cstr = cmd.toString(); 478 479 mshr_misses[access_idx] 480 .init(system->maxMasters()) 481 .name(name() + "." + cstr + "_mshr_misses") 482 .desc("number of " + cstr + " MSHR misses") 483 .flags(total | nozero | nonan) 484 ; 485 for (int i = 0; i < system->maxMasters(); i++) { 486 mshr_misses[access_idx].subname(i, system->getMasterName(i)); 487 } 488 } 489 490 demandMshrMisses 491 .name(name() + ".demand_mshr_misses") 492 .desc("number of demand (read+write) MSHR misses") 493 .flags(total | nozero | nonan) 494 ; 495 demandMshrMisses = SUM_DEMAND(mshr_misses); 496 for (int i = 0; i < system->maxMasters(); i++) { 497 demandMshrMisses.subname(i, system->getMasterName(i)); 498 } 499 500 overallMshrMisses 501 .name(name() + ".overall_mshr_misses") 502 .desc("number of overall MSHR misses") 503 .flags(total | nozero | nonan) 504 ; 505 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses); 506 for (int i = 0; i < system->maxMasters(); i++) { 507 overallMshrMisses.subname(i, system->getMasterName(i)); 508 } 509 510 // MSHR miss latency statistics 511 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 512 MemCmd cmd(access_idx); 513 const string &cstr = cmd.toString(); 514 515 mshr_miss_latency[access_idx] 516 .init(system->maxMasters()) 517 .name(name() + "." + cstr + "_mshr_miss_latency") 518 .desc("number of " + cstr + " MSHR miss cycles") 519 .flags(total | nozero | nonan) 520 ; 521 for (int i = 0; i < system->maxMasters(); i++) { 522 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i)); 523 } 524 } 525 526 demandMshrMissLatency 527 .name(name() + ".demand_mshr_miss_latency") 528 .desc("number of demand (read+write) MSHR miss cycles") 529 .flags(total | nozero | nonan) 530 ; 531 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency); 532 for (int i = 0; i < system->maxMasters(); i++) { 533 demandMshrMissLatency.subname(i, system->getMasterName(i)); 534 } 535 536 overallMshrMissLatency 537 .name(name() + ".overall_mshr_miss_latency") 538 .desc("number of overall MSHR miss cycles") 539 .flags(total | nozero | nonan) 540 ; 541 overallMshrMissLatency = 542 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency); 543 for (int i = 0; i < system->maxMasters(); i++) { 544 overallMshrMissLatency.subname(i, system->getMasterName(i)); 545 } 546 547 // MSHR uncacheable statistics 548 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 549 MemCmd cmd(access_idx); 550 const string &cstr = cmd.toString(); 551 552 mshr_uncacheable[access_idx] 553 .init(system->maxMasters()) 554 .name(name() + "." + cstr + "_mshr_uncacheable") 555 .desc("number of " + cstr + " MSHR uncacheable") 556 .flags(total | nozero | nonan) 557 ; 558 for (int i = 0; i < system->maxMasters(); i++) { 559 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i)); 560 } 561 } 562 563 overallMshrUncacheable 564 .name(name() + ".overall_mshr_uncacheable_misses") 565 .desc("number of overall MSHR uncacheable misses") 566 .flags(total | nozero | nonan) 567 ; 568 overallMshrUncacheable = 569 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable); 570 for (int i = 0; i < system->maxMasters(); i++) { 571 overallMshrUncacheable.subname(i, system->getMasterName(i)); 572 } 573 574 // MSHR miss latency statistics 575 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 576 MemCmd cmd(access_idx); 577 const string &cstr = cmd.toString(); 578 579 mshr_uncacheable_lat[access_idx] 580 .init(system->maxMasters()) 581 .name(name() + "." + cstr + "_mshr_uncacheable_latency") 582 .desc("number of " + cstr + " MSHR uncacheable cycles") 583 .flags(total | nozero | nonan) 584 ; 585 for (int i = 0; i < system->maxMasters(); i++) { 586 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i)); 587 } 588 } 589 590 overallMshrUncacheableLatency 591 .name(name() + ".overall_mshr_uncacheable_latency") 592 .desc("number of overall MSHR uncacheable cycles") 593 .flags(total | nozero | nonan) 594 ; 595 overallMshrUncacheableLatency = 596 SUM_DEMAND(mshr_uncacheable_lat) + 597 SUM_NON_DEMAND(mshr_uncacheable_lat); 598 for (int i = 0; i < system->maxMasters(); i++) { 599 overallMshrUncacheableLatency.subname(i, system->getMasterName(i)); 600 } 601 602#if 0 603 // MSHR access formulas 604 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 605 MemCmd cmd(access_idx); 606 const string &cstr = cmd.toString(); 607 608 mshrAccesses[access_idx] 609 .name(name() + "." + cstr + "_mshr_accesses") 610 .desc("number of " + cstr + " mshr accesses(hits+misses)") 611 .flags(total | nozero | nonan) 612 ; 613 mshrAccesses[access_idx] = 614 mshr_hits[access_idx] + mshr_misses[access_idx] 615 + mshr_uncacheable[access_idx]; 616 } 617 618 demandMshrAccesses 619 .name(name() + ".demand_mshr_accesses") 620 .desc("number of demand (read+write) mshr accesses") 621 .flags(total | nozero | nonan) 622 ; 623 demandMshrAccesses = demandMshrHits + demandMshrMisses; 624 625 overallMshrAccesses 626 .name(name() + ".overall_mshr_accesses") 627 .desc("number of overall (read+write) mshr accesses") 628 .flags(total | nozero | nonan) 629 ; 630 overallMshrAccesses = overallMshrHits + overallMshrMisses 631 + overallMshrUncacheable; 632#endif 633 634 // MSHR miss rate formulas 635 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 636 MemCmd cmd(access_idx); 637 const string &cstr = cmd.toString(); 638 639 mshrMissRate[access_idx] 640 .name(name() + "." + cstr + "_mshr_miss_rate") 641 .desc("mshr miss rate for " + cstr + " accesses") 642 .flags(total | nozero | nonan) 643 ; 644 mshrMissRate[access_idx] = 645 mshr_misses[access_idx] / accesses[access_idx]; 646 647 for (int i = 0; i < system->maxMasters(); i++) { 648 mshrMissRate[access_idx].subname(i, system->getMasterName(i)); 649 } 650 } 651 652 demandMshrMissRate 653 .name(name() + ".demand_mshr_miss_rate") 654 .desc("mshr miss rate for demand accesses") 655 .flags(total | nozero | nonan) 656 ; 657 demandMshrMissRate = demandMshrMisses / demandAccesses; 658 for (int i = 0; i < system->maxMasters(); i++) { 659 demandMshrMissRate.subname(i, system->getMasterName(i)); 660 } 661 662 overallMshrMissRate 663 .name(name() + ".overall_mshr_miss_rate") 664 .desc("mshr miss rate for overall accesses") 665 .flags(total | nozero | nonan) 666 ; 667 overallMshrMissRate = overallMshrMisses / overallAccesses; 668 for (int i = 0; i < system->maxMasters(); i++) { 669 overallMshrMissRate.subname(i, system->getMasterName(i)); 670 } 671 672 // mshrMiss latency formulas 673 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 674 MemCmd cmd(access_idx); 675 const string &cstr = cmd.toString(); 676 677 avgMshrMissLatency[access_idx] 678 .name(name() + "." + cstr + "_avg_mshr_miss_latency") 679 .desc("average " + cstr + " mshr miss latency") 680 .flags(total | nozero | nonan) 681 ; 682 avgMshrMissLatency[access_idx] = 683 mshr_miss_latency[access_idx] / mshr_misses[access_idx]; 684 685 for (int i = 0; i < system->maxMasters(); i++) { 686 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i)); 687 } 688 } 689 690 demandAvgMshrMissLatency 691 .name(name() + ".demand_avg_mshr_miss_latency") 692 .desc("average overall mshr miss latency") 693 .flags(total | nozero | nonan) 694 ; 695 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses; 696 for (int i = 0; i < system->maxMasters(); i++) { 697 demandAvgMshrMissLatency.subname(i, system->getMasterName(i)); 698 } 699 700 overallAvgMshrMissLatency 701 .name(name() + ".overall_avg_mshr_miss_latency") 702 .desc("average overall mshr miss latency") 703 .flags(total | nozero | nonan) 704 ; 705 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses; 706 for (int i = 0; i < system->maxMasters(); i++) { 707 overallAvgMshrMissLatency.subname(i, system->getMasterName(i)); 708 } 709 710 // mshrUncacheable latency formulas 711 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) { 712 MemCmd cmd(access_idx); 713 const string &cstr = cmd.toString(); 714 715 avgMshrUncacheableLatency[access_idx] 716 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency") 717 .desc("average " + cstr + " mshr uncacheable latency") 718 .flags(total | nozero | nonan) 719 ; 720 avgMshrUncacheableLatency[access_idx] = 721 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx]; 722 723 for (int i = 0; i < system->maxMasters(); i++) { 724 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i)); 725 } 726 } 727 728 overallAvgMshrUncacheableLatency 729 .name(name() + ".overall_avg_mshr_uncacheable_latency") 730 .desc("average overall mshr uncacheable latency") 731 .flags(total | nozero | nonan) 732 ; 733 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable; 734 for (int i = 0; i < system->maxMasters(); i++) { 735 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i)); 736 } 737 738 mshr_cap_events 739 .init(system->maxMasters()) 740 .name(name() + ".mshr_cap_events") 741 .desc("number of times MSHR cap was activated") 742 .flags(total | nozero | nonan) 743 ; 744 for (int i = 0; i < system->maxMasters(); i++) { 745 mshr_cap_events.subname(i, system->getMasterName(i)); 746 } 747 748 //software prefetching stats 749 soft_prefetch_mshr_full 750 .init(system->maxMasters()) 751 .name(name() + ".soft_prefetch_mshr_full") 752 .desc("number of mshr full events for SW prefetching instrutions") 753 .flags(total | nozero | nonan) 754 ; 755 for (int i = 0; i < system->maxMasters(); i++) { 756 soft_prefetch_mshr_full.subname(i, system->getMasterName(i)); 757 } 758 759 mshr_no_allocate_misses 760 .name(name() +".no_allocate_misses") 761 .desc("Number of misses that were no-allocate") 762 ; 763 764} 765 766unsigned int 767BaseCache::drain(DrainManager *dm) 768{ 769 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) + 770 mshrQueue.drain(dm) + writeBuffer.drain(dm); 771 772 // Set status 773 if (count != 0) { 774 setDrainState(Drainable::Draining); 775 DPRINTF(Drain, "Cache not drained\n"); 776 return count; 777 } 778 779 setDrainState(Drainable::Drained); 780 return 0; 781} 782 783BaseCache * 784BaseCacheParams::create() 785{ 786 unsigned numSets = size / (assoc * system->cacheLineSize()); 787 788 assert(tags); 789 790 if (dynamic_cast<FALRU*>(tags)) { 791 if (numSets != 1) 792 fatal("Got FALRU tags with more than one set\n"); 793 return new Cache<FALRU>(this); 794 } else if (dynamic_cast<LRU*>(tags)) { 795 if (numSets == 1) 796 warn("Consider using FALRU tags for a fully associative cache\n"); 797 return new Cache<LRU>(this); 798 } else if (dynamic_cast<RandomRepl*>(tags)) { 799 return new Cache<RandomRepl>(this); 800 } else { 801 fatal("No suitable tags selected\n"); 802 } 803} 804