base.cc revision 2811
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Erik Hallnor 29 */ 30 31/** 32 * @file 33 * Definition of BaseCache functions. 34 */ 35 36#include "mem/cache/base_cache.hh" 37#include "cpu/smt.hh" 38#include "cpu/base.hh" 39 40using namespace std; 41 42BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache, 43 bool _isCpuSide) 44 : Port(_name), cache(_cache), isCpuSide(_isCpuSide) 45{ 46 blocked = false; 47 //Start ports at null if more than one is created we should panic 48 //cpuSidePort = NULL; 49 //memSidePort = NULL; 50} 51 52void 53BaseCache::CachePort::recvStatusChange(Port::Status status) 54{ 55 cache->recvStatusChange(status, isCpuSide); 56} 57 58void 59BaseCache::CachePort::getDeviceAddressRanges(AddrRangeList &resp, 60 AddrRangeList &snoop) 61{ 62 cache->getAddressRanges(resp, snoop); 63} 64 65int 66BaseCache::CachePort::deviceBlockSize() 67{ 68 return cache->getBlockSize(); 69} 70 71bool 72BaseCache::CachePort::recvTiming(Packet *pkt) 73{ 74 return cache->doTimingAccess(pkt, this, isCpuSide); 75} 76 77Tick 78BaseCache::CachePort::recvAtomic(Packet *pkt) 79{ 80 return cache->doAtomicAccess(pkt, isCpuSide); 81} 82 83void 84BaseCache::CachePort::recvFunctional(Packet *pkt) 85{ 86 cache->doFunctionalAccess(pkt, isCpuSide); 87} 88 89void 90BaseCache::CachePort::setBlocked() 91{ 92 blocked = true; 93} 94 95void 96BaseCache::CachePort::clearBlocked() 97{ 98 blocked = false; 99} 100 101Port* 102BaseCache::getPort(const std::string &if_name) 103{ 104 if(if_name == "cpu_side") 105 { 106 if(cpuSidePort != NULL) 107 panic("Already have a cpu side for this cache\n"); 108 cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true); 109 return cpuSidePort; 110 } 111 else if(if_name == "mem_side") 112 { 113 if(memSidePort != NULL) 114 panic("Already have a mem side for this cache\n"); 115 memSidePort = new CachePort(name() + "-mem_side_port", this, false); 116 return memSidePort; 117 } 118 else panic("Port name %s unrecognized\n", if_name); 119} 120 121void 122BaseCache::regStats() 123{ 124 Request temp_req; 125 Packet::Command temp_cmd = Packet::ReadReq; 126 Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary 127 128 using namespace Stats; 129 130 // Hit statistics 131 for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { 132 Packet::Command cmd = (Packet::Command)access_idx; 133 const string &cstr = temp_pkt.cmdIdxToString(cmd); 134 135 hits[access_idx] 136 .init(maxThreadsPerCPU) 137 .name(name() + "." + cstr + "_hits") 138 .desc("number of " + cstr + " hits") 139 .flags(total | nozero | nonan) 140 ; 141 } 142 143 demandHits 144 .name(name() + ".demand_hits") 145 .desc("number of demand (read+write) hits") 146 .flags(total) 147 ; 148 demandHits = hits[Packet::ReadReq] + hits[Packet::WriteReq]; 149 150 overallHits 151 .name(name() + ".overall_hits") 152 .desc("number of overall hits") 153 .flags(total) 154 ; 155 overallHits = demandHits + hits[Packet::SoftPFReq] + hits[Packet::HardPFReq] 156 + hits[Packet::Writeback]; 157 158 // Miss statistics 159 for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { 160 Packet::Command cmd = (Packet::Command)access_idx; 161 const string &cstr = temp_pkt.cmdIdxToString(cmd); 162 163 misses[access_idx] 164 .init(maxThreadsPerCPU) 165 .name(name() + "." + cstr + "_misses") 166 .desc("number of " + cstr + " misses") 167 .flags(total | nozero | nonan) 168 ; 169 } 170 171 demandMisses 172 .name(name() + ".demand_misses") 173 .desc("number of demand (read+write) misses") 174 .flags(total) 175 ; 176 demandMisses = misses[Packet::ReadReq] + misses[Packet::WriteReq]; 177 178 overallMisses 179 .name(name() + ".overall_misses") 180 .desc("number of overall misses") 181 .flags(total) 182 ; 183 overallMisses = demandMisses + misses[Packet::SoftPFReq] + 184 misses[Packet::HardPFReq] + misses[Packet::Writeback]; 185 186 // Miss latency statistics 187 for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { 188 Packet::Command cmd = (Packet::Command)access_idx; 189 const string &cstr = temp_pkt.cmdIdxToString(cmd); 190 191 missLatency[access_idx] 192 .init(maxThreadsPerCPU) 193 .name(name() + "." + cstr + "_miss_latency") 194 .desc("number of " + cstr + " miss cycles") 195 .flags(total | nozero | nonan) 196 ; 197 } 198 199 demandMissLatency 200 .name(name() + ".demand_miss_latency") 201 .desc("number of demand (read+write) miss cycles") 202 .flags(total) 203 ; 204 demandMissLatency = missLatency[Packet::ReadReq] + missLatency[Packet::WriteReq]; 205 206 overallMissLatency 207 .name(name() + ".overall_miss_latency") 208 .desc("number of overall miss cycles") 209 .flags(total) 210 ; 211 overallMissLatency = demandMissLatency + missLatency[Packet::SoftPFReq] + 212 missLatency[Packet::HardPFReq]; 213 214 // access formulas 215 for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { 216 Packet::Command cmd = (Packet::Command)access_idx; 217 const string &cstr = temp_pkt.cmdIdxToString(cmd); 218 219 accesses[access_idx] 220 .name(name() + "." + cstr + "_accesses") 221 .desc("number of " + cstr + " accesses(hits+misses)") 222 .flags(total | nozero | nonan) 223 ; 224 225 accesses[access_idx] = hits[access_idx] + misses[access_idx]; 226 } 227 228 demandAccesses 229 .name(name() + ".demand_accesses") 230 .desc("number of demand (read+write) accesses") 231 .flags(total) 232 ; 233 demandAccesses = demandHits + demandMisses; 234 235 overallAccesses 236 .name(name() + ".overall_accesses") 237 .desc("number of overall (read+write) accesses") 238 .flags(total) 239 ; 240 overallAccesses = overallHits + overallMisses; 241 242 // miss rate formulas 243 for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { 244 Packet::Command cmd = (Packet::Command)access_idx; 245 const string &cstr = temp_pkt.cmdIdxToString(cmd); 246 247 missRate[access_idx] 248 .name(name() + "." + cstr + "_miss_rate") 249 .desc("miss rate for " + cstr + " accesses") 250 .flags(total | nozero | nonan) 251 ; 252 253 missRate[access_idx] = misses[access_idx] / accesses[access_idx]; 254 } 255 256 demandMissRate 257 .name(name() + ".demand_miss_rate") 258 .desc("miss rate for demand accesses") 259 .flags(total) 260 ; 261 demandMissRate = demandMisses / demandAccesses; 262 263 overallMissRate 264 .name(name() + ".overall_miss_rate") 265 .desc("miss rate for overall accesses") 266 .flags(total) 267 ; 268 overallMissRate = overallMisses / overallAccesses; 269 270 // miss latency formulas 271 for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { 272 Packet::Command cmd = (Packet::Command)access_idx; 273 const string &cstr = temp_pkt.cmdIdxToString(cmd); 274 275 avgMissLatency[access_idx] 276 .name(name() + "." + cstr + "_avg_miss_latency") 277 .desc("average " + cstr + " miss latency") 278 .flags(total | nozero | nonan) 279 ; 280 281 avgMissLatency[access_idx] = 282 missLatency[access_idx] / misses[access_idx]; 283 } 284 285 demandAvgMissLatency 286 .name(name() + ".demand_avg_miss_latency") 287 .desc("average overall miss latency") 288 .flags(total) 289 ; 290 demandAvgMissLatency = demandMissLatency / demandMisses; 291 292 overallAvgMissLatency 293 .name(name() + ".overall_avg_miss_latency") 294 .desc("average overall miss latency") 295 .flags(total) 296 ; 297 overallAvgMissLatency = overallMissLatency / overallMisses; 298 299 blocked_cycles.init(NUM_BLOCKED_CAUSES); 300 blocked_cycles 301 .name(name() + ".blocked_cycles") 302 .desc("number of cycles access was blocked") 303 .subname(Blocked_NoMSHRs, "no_mshrs") 304 .subname(Blocked_NoTargets, "no_targets") 305 ; 306 307 308 blocked_causes.init(NUM_BLOCKED_CAUSES); 309 blocked_causes 310 .name(name() + ".blocked") 311 .desc("number of cycles access was blocked") 312 .subname(Blocked_NoMSHRs, "no_mshrs") 313 .subname(Blocked_NoTargets, "no_targets") 314 ; 315 316 avg_blocked 317 .name(name() + ".avg_blocked_cycles") 318 .desc("average number of cycles each access was blocked") 319 .subname(Blocked_NoMSHRs, "no_mshrs") 320 .subname(Blocked_NoTargets, "no_targets") 321 ; 322 323 avg_blocked = blocked_cycles / blocked_causes; 324 325 fastWrites 326 .name(name() + ".fast_writes") 327 .desc("number of fast writes performed") 328 ; 329 330 cacheCopies 331 .name(name() + ".cache_copies") 332 .desc("number of cache copies performed") 333 ; 334} 335