base.cc (10884:c60acdbdd6ad) base.cc (10885:3ac92bf1f31f)
1/*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
48#include "debug/Cache.hh"
49#include "debug/Drain.hh"
50#include "mem/cache/tags/fa_lru.hh"
51#include "mem/cache/tags/lru.hh"
52#include "mem/cache/tags/random_repl.hh"
53#include "mem/cache/base.hh"
54#include "mem/cache/cache.hh"
55#include "mem/cache/mshr.hh"
56#include "sim/full_system.hh"
57
58using namespace std;
59
60BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
61 BaseCache *_cache,
62 const std::string &_label)
63 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
64 blocked(false), mustSendRetry(false), sendRetryEvent(this)
65{
66}
67
68BaseCache::BaseCache(const Params *p)
69 : MemObject(p),
70 cpuSidePort(nullptr), memSidePort(nullptr),
71 mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve, MSHRQueue_MSHRs),
72 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 0,
73 MSHRQueue_WriteBuffer),
74 blkSize(p->system->cacheLineSize()),
75 lookupLatency(p->hit_latency),
76 forwardLatency(p->hit_latency),
77 fillLatency(p->response_latency),
78 responseLatency(p->response_latency),
79 numTarget(p->tgts_per_mshr),
80 forwardSnoops(p->forward_snoops),
81 isTopLevel(p->is_top_level),
82 isReadOnly(p->is_read_only),
83 blocked(0),
84 order(0),
85 noTargetMSHR(NULL),
86 missCount(p->max_miss_count),
87 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
88 system(p->system)
89{
90}
91
92void
93BaseCache::CacheSlavePort::setBlocked()
94{
95 assert(!blocked);
96 DPRINTF(CachePort, "Port is blocking new requests\n");
97 blocked = true;
98 // if we already scheduled a retry in this cycle, but it has not yet
99 // happened, cancel it
100 if (sendRetryEvent.scheduled()) {
101 owner.deschedule(sendRetryEvent);
102 DPRINTF(CachePort, "Port descheduled retry\n");
103 mustSendRetry = true;
104 }
105}
106
107void
108BaseCache::CacheSlavePort::clearBlocked()
109{
110 assert(blocked);
111 DPRINTF(CachePort, "Port is accepting new requests\n");
112 blocked = false;
113 if (mustSendRetry) {
114 // @TODO: need to find a better time (next cycle?)
115 owner.schedule(sendRetryEvent, curTick() + 1);
116 }
117}
118
119void
120BaseCache::CacheSlavePort::processSendRetry()
121{
122 DPRINTF(CachePort, "Port is sending retry\n");
123
124 // reset the flag and call retry
125 mustSendRetry = false;
126 sendRetryReq();
127}
128
129void
130BaseCache::init()
131{
132 if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
133 fatal("Cache ports on %s are not connected\n", name());
134 cpuSidePort->sendRangeChange();
135}
136
137BaseMasterPort &
138BaseCache::getMasterPort(const std::string &if_name, PortID idx)
139{
140 if (if_name == "mem_side") {
141 return *memSidePort;
142 } else {
143 return MemObject::getMasterPort(if_name, idx);
144 }
145}
146
147BaseSlavePort &
148BaseCache::getSlavePort(const std::string &if_name, PortID idx)
149{
150 if (if_name == "cpu_side") {
151 return *cpuSidePort;
152 } else {
153 return MemObject::getSlavePort(if_name, idx);
154 }
155}
156
157bool
158BaseCache::inRange(Addr addr) const
159{
160 for (const auto& r : addrRanges) {
161 if (r.contains(addr)) {
162 return true;
163 }
164 }
165 return false;
166}
167
168void
169BaseCache::regStats()
170{
171 using namespace Stats;
172
173 // Hit statistics
174 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
175 MemCmd cmd(access_idx);
176 const string &cstr = cmd.toString();
177
178 hits[access_idx]
179 .init(system->maxMasters())
180 .name(name() + "." + cstr + "_hits")
181 .desc("number of " + cstr + " hits")
182 .flags(total | nozero | nonan)
183 ;
184 for (int i = 0; i < system->maxMasters(); i++) {
185 hits[access_idx].subname(i, system->getMasterName(i));
186 }
187 }
188
189// These macros make it easier to sum the right subset of commands and
190// to change the subset of commands that are considered "demand" vs
191// "non-demand"
192#define SUM_DEMAND(s) \
1/*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
48#include "debug/Cache.hh"
49#include "debug/Drain.hh"
50#include "mem/cache/tags/fa_lru.hh"
51#include "mem/cache/tags/lru.hh"
52#include "mem/cache/tags/random_repl.hh"
53#include "mem/cache/base.hh"
54#include "mem/cache/cache.hh"
55#include "mem/cache/mshr.hh"
56#include "sim/full_system.hh"
57
58using namespace std;
59
60BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
61 BaseCache *_cache,
62 const std::string &_label)
63 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
64 blocked(false), mustSendRetry(false), sendRetryEvent(this)
65{
66}
67
68BaseCache::BaseCache(const Params *p)
69 : MemObject(p),
70 cpuSidePort(nullptr), memSidePort(nullptr),
71 mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve, MSHRQueue_MSHRs),
72 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 0,
73 MSHRQueue_WriteBuffer),
74 blkSize(p->system->cacheLineSize()),
75 lookupLatency(p->hit_latency),
76 forwardLatency(p->hit_latency),
77 fillLatency(p->response_latency),
78 responseLatency(p->response_latency),
79 numTarget(p->tgts_per_mshr),
80 forwardSnoops(p->forward_snoops),
81 isTopLevel(p->is_top_level),
82 isReadOnly(p->is_read_only),
83 blocked(0),
84 order(0),
85 noTargetMSHR(NULL),
86 missCount(p->max_miss_count),
87 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
88 system(p->system)
89{
90}
91
92void
93BaseCache::CacheSlavePort::setBlocked()
94{
95 assert(!blocked);
96 DPRINTF(CachePort, "Port is blocking new requests\n");
97 blocked = true;
98 // if we already scheduled a retry in this cycle, but it has not yet
99 // happened, cancel it
100 if (sendRetryEvent.scheduled()) {
101 owner.deschedule(sendRetryEvent);
102 DPRINTF(CachePort, "Port descheduled retry\n");
103 mustSendRetry = true;
104 }
105}
106
107void
108BaseCache::CacheSlavePort::clearBlocked()
109{
110 assert(blocked);
111 DPRINTF(CachePort, "Port is accepting new requests\n");
112 blocked = false;
113 if (mustSendRetry) {
114 // @TODO: need to find a better time (next cycle?)
115 owner.schedule(sendRetryEvent, curTick() + 1);
116 }
117}
118
119void
120BaseCache::CacheSlavePort::processSendRetry()
121{
122 DPRINTF(CachePort, "Port is sending retry\n");
123
124 // reset the flag and call retry
125 mustSendRetry = false;
126 sendRetryReq();
127}
128
129void
130BaseCache::init()
131{
132 if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
133 fatal("Cache ports on %s are not connected\n", name());
134 cpuSidePort->sendRangeChange();
135}
136
137BaseMasterPort &
138BaseCache::getMasterPort(const std::string &if_name, PortID idx)
139{
140 if (if_name == "mem_side") {
141 return *memSidePort;
142 } else {
143 return MemObject::getMasterPort(if_name, idx);
144 }
145}
146
147BaseSlavePort &
148BaseCache::getSlavePort(const std::string &if_name, PortID idx)
149{
150 if (if_name == "cpu_side") {
151 return *cpuSidePort;
152 } else {
153 return MemObject::getSlavePort(if_name, idx);
154 }
155}
156
157bool
158BaseCache::inRange(Addr addr) const
159{
160 for (const auto& r : addrRanges) {
161 if (r.contains(addr)) {
162 return true;
163 }
164 }
165 return false;
166}
167
168void
169BaseCache::regStats()
170{
171 using namespace Stats;
172
173 // Hit statistics
174 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
175 MemCmd cmd(access_idx);
176 const string &cstr = cmd.toString();
177
178 hits[access_idx]
179 .init(system->maxMasters())
180 .name(name() + "." + cstr + "_hits")
181 .desc("number of " + cstr + " hits")
182 .flags(total | nozero | nonan)
183 ;
184 for (int i = 0; i < system->maxMasters(); i++) {
185 hits[access_idx].subname(i, system->getMasterName(i));
186 }
187 }
188
189// These macros make it easier to sum the right subset of commands and
190// to change the subset of commands that are considered "demand" vs
191// "non-demand"
192#define SUM_DEMAND(s) \
193 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
193 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + \
194 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
194
195// should writebacks be included here? prior code was inconsistent...
196#define SUM_NON_DEMAND(s) \
197 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
198
199 demandHits
200 .name(name() + ".demand_hits")
201 .desc("number of demand (read+write) hits")
202 .flags(total | nozero | nonan)
203 ;
204 demandHits = SUM_DEMAND(hits);
205 for (int i = 0; i < system->maxMasters(); i++) {
206 demandHits.subname(i, system->getMasterName(i));
207 }
208
209 overallHits
210 .name(name() + ".overall_hits")
211 .desc("number of overall hits")
212 .flags(total | nozero | nonan)
213 ;
214 overallHits = demandHits + SUM_NON_DEMAND(hits);
215 for (int i = 0; i < system->maxMasters(); i++) {
216 overallHits.subname(i, system->getMasterName(i));
217 }
218
219 // Miss statistics
220 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
221 MemCmd cmd(access_idx);
222 const string &cstr = cmd.toString();
223
224 misses[access_idx]
225 .init(system->maxMasters())
226 .name(name() + "." + cstr + "_misses")
227 .desc("number of " + cstr + " misses")
228 .flags(total | nozero | nonan)
229 ;
230 for (int i = 0; i < system->maxMasters(); i++) {
231 misses[access_idx].subname(i, system->getMasterName(i));
232 }
233 }
234
235 demandMisses
236 .name(name() + ".demand_misses")
237 .desc("number of demand (read+write) misses")
238 .flags(total | nozero | nonan)
239 ;
240 demandMisses = SUM_DEMAND(misses);
241 for (int i = 0; i < system->maxMasters(); i++) {
242 demandMisses.subname(i, system->getMasterName(i));
243 }
244
245 overallMisses
246 .name(name() + ".overall_misses")
247 .desc("number of overall misses")
248 .flags(total | nozero | nonan)
249 ;
250 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
251 for (int i = 0; i < system->maxMasters(); i++) {
252 overallMisses.subname(i, system->getMasterName(i));
253 }
254
255 // Miss latency statistics
256 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
257 MemCmd cmd(access_idx);
258 const string &cstr = cmd.toString();
259
260 missLatency[access_idx]
261 .init(system->maxMasters())
262 .name(name() + "." + cstr + "_miss_latency")
263 .desc("number of " + cstr + " miss cycles")
264 .flags(total | nozero | nonan)
265 ;
266 for (int i = 0; i < system->maxMasters(); i++) {
267 missLatency[access_idx].subname(i, system->getMasterName(i));
268 }
269 }
270
271 demandMissLatency
272 .name(name() + ".demand_miss_latency")
273 .desc("number of demand (read+write) miss cycles")
274 .flags(total | nozero | nonan)
275 ;
276 demandMissLatency = SUM_DEMAND(missLatency);
277 for (int i = 0; i < system->maxMasters(); i++) {
278 demandMissLatency.subname(i, system->getMasterName(i));
279 }
280
281 overallMissLatency
282 .name(name() + ".overall_miss_latency")
283 .desc("number of overall miss cycles")
284 .flags(total | nozero | nonan)
285 ;
286 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
287 for (int i = 0; i < system->maxMasters(); i++) {
288 overallMissLatency.subname(i, system->getMasterName(i));
289 }
290
291 // access formulas
292 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
293 MemCmd cmd(access_idx);
294 const string &cstr = cmd.toString();
295
296 accesses[access_idx]
297 .name(name() + "." + cstr + "_accesses")
298 .desc("number of " + cstr + " accesses(hits+misses)")
299 .flags(total | nozero | nonan)
300 ;
301 accesses[access_idx] = hits[access_idx] + misses[access_idx];
302
303 for (int i = 0; i < system->maxMasters(); i++) {
304 accesses[access_idx].subname(i, system->getMasterName(i));
305 }
306 }
307
308 demandAccesses
309 .name(name() + ".demand_accesses")
310 .desc("number of demand (read+write) accesses")
311 .flags(total | nozero | nonan)
312 ;
313 demandAccesses = demandHits + demandMisses;
314 for (int i = 0; i < system->maxMasters(); i++) {
315 demandAccesses.subname(i, system->getMasterName(i));
316 }
317
318 overallAccesses
319 .name(name() + ".overall_accesses")
320 .desc("number of overall (read+write) accesses")
321 .flags(total | nozero | nonan)
322 ;
323 overallAccesses = overallHits + overallMisses;
324 for (int i = 0; i < system->maxMasters(); i++) {
325 overallAccesses.subname(i, system->getMasterName(i));
326 }
327
328 // miss rate formulas
329 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
330 MemCmd cmd(access_idx);
331 const string &cstr = cmd.toString();
332
333 missRate[access_idx]
334 .name(name() + "." + cstr + "_miss_rate")
335 .desc("miss rate for " + cstr + " accesses")
336 .flags(total | nozero | nonan)
337 ;
338 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
339
340 for (int i = 0; i < system->maxMasters(); i++) {
341 missRate[access_idx].subname(i, system->getMasterName(i));
342 }
343 }
344
345 demandMissRate
346 .name(name() + ".demand_miss_rate")
347 .desc("miss rate for demand accesses")
348 .flags(total | nozero | nonan)
349 ;
350 demandMissRate = demandMisses / demandAccesses;
351 for (int i = 0; i < system->maxMasters(); i++) {
352 demandMissRate.subname(i, system->getMasterName(i));
353 }
354
355 overallMissRate
356 .name(name() + ".overall_miss_rate")
357 .desc("miss rate for overall accesses")
358 .flags(total | nozero | nonan)
359 ;
360 overallMissRate = overallMisses / overallAccesses;
361 for (int i = 0; i < system->maxMasters(); i++) {
362 overallMissRate.subname(i, system->getMasterName(i));
363 }
364
365 // miss latency formulas
366 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
367 MemCmd cmd(access_idx);
368 const string &cstr = cmd.toString();
369
370 avgMissLatency[access_idx]
371 .name(name() + "." + cstr + "_avg_miss_latency")
372 .desc("average " + cstr + " miss latency")
373 .flags(total | nozero | nonan)
374 ;
375 avgMissLatency[access_idx] =
376 missLatency[access_idx] / misses[access_idx];
377
378 for (int i = 0; i < system->maxMasters(); i++) {
379 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
380 }
381 }
382
383 demandAvgMissLatency
384 .name(name() + ".demand_avg_miss_latency")
385 .desc("average overall miss latency")
386 .flags(total | nozero | nonan)
387 ;
388 demandAvgMissLatency = demandMissLatency / demandMisses;
389 for (int i = 0; i < system->maxMasters(); i++) {
390 demandAvgMissLatency.subname(i, system->getMasterName(i));
391 }
392
393 overallAvgMissLatency
394 .name(name() + ".overall_avg_miss_latency")
395 .desc("average overall miss latency")
396 .flags(total | nozero | nonan)
397 ;
398 overallAvgMissLatency = overallMissLatency / overallMisses;
399 for (int i = 0; i < system->maxMasters(); i++) {
400 overallAvgMissLatency.subname(i, system->getMasterName(i));
401 }
402
403 blocked_cycles.init(NUM_BLOCKED_CAUSES);
404 blocked_cycles
405 .name(name() + ".blocked_cycles")
406 .desc("number of cycles access was blocked")
407 .subname(Blocked_NoMSHRs, "no_mshrs")
408 .subname(Blocked_NoTargets, "no_targets")
409 ;
410
411
412 blocked_causes.init(NUM_BLOCKED_CAUSES);
413 blocked_causes
414 .name(name() + ".blocked")
415 .desc("number of cycles access was blocked")
416 .subname(Blocked_NoMSHRs, "no_mshrs")
417 .subname(Blocked_NoTargets, "no_targets")
418 ;
419
420 avg_blocked
421 .name(name() + ".avg_blocked_cycles")
422 .desc("average number of cycles each access was blocked")
423 .subname(Blocked_NoMSHRs, "no_mshrs")
424 .subname(Blocked_NoTargets, "no_targets")
425 ;
426
427 avg_blocked = blocked_cycles / blocked_causes;
428
429 fastWrites
430 .name(name() + ".fast_writes")
431 .desc("number of fast writes performed")
432 ;
433
434 cacheCopies
435 .name(name() + ".cache_copies")
436 .desc("number of cache copies performed")
437 ;
438
439 writebacks
440 .init(system->maxMasters())
441 .name(name() + ".writebacks")
442 .desc("number of writebacks")
443 .flags(total | nozero | nonan)
444 ;
445 for (int i = 0; i < system->maxMasters(); i++) {
446 writebacks.subname(i, system->getMasterName(i));
447 }
448
449 // MSHR statistics
450 // MSHR hit statistics
451 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
452 MemCmd cmd(access_idx);
453 const string &cstr = cmd.toString();
454
455 mshr_hits[access_idx]
456 .init(system->maxMasters())
457 .name(name() + "." + cstr + "_mshr_hits")
458 .desc("number of " + cstr + " MSHR hits")
459 .flags(total | nozero | nonan)
460 ;
461 for (int i = 0; i < system->maxMasters(); i++) {
462 mshr_hits[access_idx].subname(i, system->getMasterName(i));
463 }
464 }
465
466 demandMshrHits
467 .name(name() + ".demand_mshr_hits")
468 .desc("number of demand (read+write) MSHR hits")
469 .flags(total | nozero | nonan)
470 ;
471 demandMshrHits = SUM_DEMAND(mshr_hits);
472 for (int i = 0; i < system->maxMasters(); i++) {
473 demandMshrHits.subname(i, system->getMasterName(i));
474 }
475
476 overallMshrHits
477 .name(name() + ".overall_mshr_hits")
478 .desc("number of overall MSHR hits")
479 .flags(total | nozero | nonan)
480 ;
481 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
482 for (int i = 0; i < system->maxMasters(); i++) {
483 overallMshrHits.subname(i, system->getMasterName(i));
484 }
485
486 // MSHR miss statistics
487 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
488 MemCmd cmd(access_idx);
489 const string &cstr = cmd.toString();
490
491 mshr_misses[access_idx]
492 .init(system->maxMasters())
493 .name(name() + "." + cstr + "_mshr_misses")
494 .desc("number of " + cstr + " MSHR misses")
495 .flags(total | nozero | nonan)
496 ;
497 for (int i = 0; i < system->maxMasters(); i++) {
498 mshr_misses[access_idx].subname(i, system->getMasterName(i));
499 }
500 }
501
502 demandMshrMisses
503 .name(name() + ".demand_mshr_misses")
504 .desc("number of demand (read+write) MSHR misses")
505 .flags(total | nozero | nonan)
506 ;
507 demandMshrMisses = SUM_DEMAND(mshr_misses);
508 for (int i = 0; i < system->maxMasters(); i++) {
509 demandMshrMisses.subname(i, system->getMasterName(i));
510 }
511
512 overallMshrMisses
513 .name(name() + ".overall_mshr_misses")
514 .desc("number of overall MSHR misses")
515 .flags(total | nozero | nonan)
516 ;
517 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
518 for (int i = 0; i < system->maxMasters(); i++) {
519 overallMshrMisses.subname(i, system->getMasterName(i));
520 }
521
522 // MSHR miss latency statistics
523 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
524 MemCmd cmd(access_idx);
525 const string &cstr = cmd.toString();
526
527 mshr_miss_latency[access_idx]
528 .init(system->maxMasters())
529 .name(name() + "." + cstr + "_mshr_miss_latency")
530 .desc("number of " + cstr + " MSHR miss cycles")
531 .flags(total | nozero | nonan)
532 ;
533 for (int i = 0; i < system->maxMasters(); i++) {
534 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
535 }
536 }
537
538 demandMshrMissLatency
539 .name(name() + ".demand_mshr_miss_latency")
540 .desc("number of demand (read+write) MSHR miss cycles")
541 .flags(total | nozero | nonan)
542 ;
543 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
544 for (int i = 0; i < system->maxMasters(); i++) {
545 demandMshrMissLatency.subname(i, system->getMasterName(i));
546 }
547
548 overallMshrMissLatency
549 .name(name() + ".overall_mshr_miss_latency")
550 .desc("number of overall MSHR miss cycles")
551 .flags(total | nozero | nonan)
552 ;
553 overallMshrMissLatency =
554 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
555 for (int i = 0; i < system->maxMasters(); i++) {
556 overallMshrMissLatency.subname(i, system->getMasterName(i));
557 }
558
559 // MSHR uncacheable statistics
560 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
561 MemCmd cmd(access_idx);
562 const string &cstr = cmd.toString();
563
564 mshr_uncacheable[access_idx]
565 .init(system->maxMasters())
566 .name(name() + "." + cstr + "_mshr_uncacheable")
567 .desc("number of " + cstr + " MSHR uncacheable")
568 .flags(total | nozero | nonan)
569 ;
570 for (int i = 0; i < system->maxMasters(); i++) {
571 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
572 }
573 }
574
575 overallMshrUncacheable
576 .name(name() + ".overall_mshr_uncacheable_misses")
577 .desc("number of overall MSHR uncacheable misses")
578 .flags(total | nozero | nonan)
579 ;
580 overallMshrUncacheable =
581 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
582 for (int i = 0; i < system->maxMasters(); i++) {
583 overallMshrUncacheable.subname(i, system->getMasterName(i));
584 }
585
586 // MSHR miss latency statistics
587 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
588 MemCmd cmd(access_idx);
589 const string &cstr = cmd.toString();
590
591 mshr_uncacheable_lat[access_idx]
592 .init(system->maxMasters())
593 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
594 .desc("number of " + cstr + " MSHR uncacheable cycles")
595 .flags(total | nozero | nonan)
596 ;
597 for (int i = 0; i < system->maxMasters(); i++) {
598 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
599 }
600 }
601
602 overallMshrUncacheableLatency
603 .name(name() + ".overall_mshr_uncacheable_latency")
604 .desc("number of overall MSHR uncacheable cycles")
605 .flags(total | nozero | nonan)
606 ;
607 overallMshrUncacheableLatency =
608 SUM_DEMAND(mshr_uncacheable_lat) +
609 SUM_NON_DEMAND(mshr_uncacheable_lat);
610 for (int i = 0; i < system->maxMasters(); i++) {
611 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
612 }
613
614#if 0
615 // MSHR access 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 mshrAccesses[access_idx]
621 .name(name() + "." + cstr + "_mshr_accesses")
622 .desc("number of " + cstr + " mshr accesses(hits+misses)")
623 .flags(total | nozero | nonan)
624 ;
625 mshrAccesses[access_idx] =
626 mshr_hits[access_idx] + mshr_misses[access_idx]
627 + mshr_uncacheable[access_idx];
628 }
629
630 demandMshrAccesses
631 .name(name() + ".demand_mshr_accesses")
632 .desc("number of demand (read+write) mshr accesses")
633 .flags(total | nozero | nonan)
634 ;
635 demandMshrAccesses = demandMshrHits + demandMshrMisses;
636
637 overallMshrAccesses
638 .name(name() + ".overall_mshr_accesses")
639 .desc("number of overall (read+write) mshr accesses")
640 .flags(total | nozero | nonan)
641 ;
642 overallMshrAccesses = overallMshrHits + overallMshrMisses
643 + overallMshrUncacheable;
644#endif
645
646 // MSHR miss rate formulas
647 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
648 MemCmd cmd(access_idx);
649 const string &cstr = cmd.toString();
650
651 mshrMissRate[access_idx]
652 .name(name() + "." + cstr + "_mshr_miss_rate")
653 .desc("mshr miss rate for " + cstr + " accesses")
654 .flags(total | nozero | nonan)
655 ;
656 mshrMissRate[access_idx] =
657 mshr_misses[access_idx] / accesses[access_idx];
658
659 for (int i = 0; i < system->maxMasters(); i++) {
660 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
661 }
662 }
663
664 demandMshrMissRate
665 .name(name() + ".demand_mshr_miss_rate")
666 .desc("mshr miss rate for demand accesses")
667 .flags(total | nozero | nonan)
668 ;
669 demandMshrMissRate = demandMshrMisses / demandAccesses;
670 for (int i = 0; i < system->maxMasters(); i++) {
671 demandMshrMissRate.subname(i, system->getMasterName(i));
672 }
673
674 overallMshrMissRate
675 .name(name() + ".overall_mshr_miss_rate")
676 .desc("mshr miss rate for overall accesses")
677 .flags(total | nozero | nonan)
678 ;
679 overallMshrMissRate = overallMshrMisses / overallAccesses;
680 for (int i = 0; i < system->maxMasters(); i++) {
681 overallMshrMissRate.subname(i, system->getMasterName(i));
682 }
683
684 // mshrMiss latency formulas
685 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
686 MemCmd cmd(access_idx);
687 const string &cstr = cmd.toString();
688
689 avgMshrMissLatency[access_idx]
690 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
691 .desc("average " + cstr + " mshr miss latency")
692 .flags(total | nozero | nonan)
693 ;
694 avgMshrMissLatency[access_idx] =
695 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
696
697 for (int i = 0; i < system->maxMasters(); i++) {
698 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
699 }
700 }
701
702 demandAvgMshrMissLatency
703 .name(name() + ".demand_avg_mshr_miss_latency")
704 .desc("average overall mshr miss latency")
705 .flags(total | nozero | nonan)
706 ;
707 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
708 for (int i = 0; i < system->maxMasters(); i++) {
709 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
710 }
711
712 overallAvgMshrMissLatency
713 .name(name() + ".overall_avg_mshr_miss_latency")
714 .desc("average overall mshr miss latency")
715 .flags(total | nozero | nonan)
716 ;
717 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
718 for (int i = 0; i < system->maxMasters(); i++) {
719 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
720 }
721
722 // mshrUncacheable latency formulas
723 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
724 MemCmd cmd(access_idx);
725 const string &cstr = cmd.toString();
726
727 avgMshrUncacheableLatency[access_idx]
728 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
729 .desc("average " + cstr + " mshr uncacheable latency")
730 .flags(total | nozero | nonan)
731 ;
732 avgMshrUncacheableLatency[access_idx] =
733 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
734
735 for (int i = 0; i < system->maxMasters(); i++) {
736 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
737 }
738 }
739
740 overallAvgMshrUncacheableLatency
741 .name(name() + ".overall_avg_mshr_uncacheable_latency")
742 .desc("average overall mshr uncacheable latency")
743 .flags(total | nozero | nonan)
744 ;
745 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
746 for (int i = 0; i < system->maxMasters(); i++) {
747 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
748 }
749
750 mshr_cap_events
751 .init(system->maxMasters())
752 .name(name() + ".mshr_cap_events")
753 .desc("number of times MSHR cap was activated")
754 .flags(total | nozero | nonan)
755 ;
756 for (int i = 0; i < system->maxMasters(); i++) {
757 mshr_cap_events.subname(i, system->getMasterName(i));
758 }
759
760 //software prefetching stats
761 soft_prefetch_mshr_full
762 .init(system->maxMasters())
763 .name(name() + ".soft_prefetch_mshr_full")
764 .desc("number of mshr full events for SW prefetching instrutions")
765 .flags(total | nozero | nonan)
766 ;
767 for (int i = 0; i < system->maxMasters(); i++) {
768 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
769 }
770
771 mshr_no_allocate_misses
772 .name(name() +".no_allocate_misses")
773 .desc("Number of misses that were no-allocate")
774 ;
775
776}
777
778unsigned int
779BaseCache::drain(DrainManager *dm)
780{
781 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
782 mshrQueue.drain(dm) + writeBuffer.drain(dm);
783
784 // Set status
785 if (count != 0) {
786 setDrainState(Drainable::Draining);
787 DPRINTF(Drain, "Cache not drained\n");
788 return count;
789 }
790
791 setDrainState(Drainable::Drained);
792 return 0;
793}
794
795BaseCache *
796BaseCacheParams::create()
797{
798 assert(tags);
799
800 return new Cache(this);
801}
195
196// should writebacks be included here? prior code was inconsistent...
197#define SUM_NON_DEMAND(s) \
198 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
199
200 demandHits
201 .name(name() + ".demand_hits")
202 .desc("number of demand (read+write) hits")
203 .flags(total | nozero | nonan)
204 ;
205 demandHits = SUM_DEMAND(hits);
206 for (int i = 0; i < system->maxMasters(); i++) {
207 demandHits.subname(i, system->getMasterName(i));
208 }
209
210 overallHits
211 .name(name() + ".overall_hits")
212 .desc("number of overall hits")
213 .flags(total | nozero | nonan)
214 ;
215 overallHits = demandHits + SUM_NON_DEMAND(hits);
216 for (int i = 0; i < system->maxMasters(); i++) {
217 overallHits.subname(i, system->getMasterName(i));
218 }
219
220 // Miss statistics
221 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
222 MemCmd cmd(access_idx);
223 const string &cstr = cmd.toString();
224
225 misses[access_idx]
226 .init(system->maxMasters())
227 .name(name() + "." + cstr + "_misses")
228 .desc("number of " + cstr + " misses")
229 .flags(total | nozero | nonan)
230 ;
231 for (int i = 0; i < system->maxMasters(); i++) {
232 misses[access_idx].subname(i, system->getMasterName(i));
233 }
234 }
235
236 demandMisses
237 .name(name() + ".demand_misses")
238 .desc("number of demand (read+write) misses")
239 .flags(total | nozero | nonan)
240 ;
241 demandMisses = SUM_DEMAND(misses);
242 for (int i = 0; i < system->maxMasters(); i++) {
243 demandMisses.subname(i, system->getMasterName(i));
244 }
245
246 overallMisses
247 .name(name() + ".overall_misses")
248 .desc("number of overall misses")
249 .flags(total | nozero | nonan)
250 ;
251 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
252 for (int i = 0; i < system->maxMasters(); i++) {
253 overallMisses.subname(i, system->getMasterName(i));
254 }
255
256 // Miss latency statistics
257 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
258 MemCmd cmd(access_idx);
259 const string &cstr = cmd.toString();
260
261 missLatency[access_idx]
262 .init(system->maxMasters())
263 .name(name() + "." + cstr + "_miss_latency")
264 .desc("number of " + cstr + " miss cycles")
265 .flags(total | nozero | nonan)
266 ;
267 for (int i = 0; i < system->maxMasters(); i++) {
268 missLatency[access_idx].subname(i, system->getMasterName(i));
269 }
270 }
271
272 demandMissLatency
273 .name(name() + ".demand_miss_latency")
274 .desc("number of demand (read+write) miss cycles")
275 .flags(total | nozero | nonan)
276 ;
277 demandMissLatency = SUM_DEMAND(missLatency);
278 for (int i = 0; i < system->maxMasters(); i++) {
279 demandMissLatency.subname(i, system->getMasterName(i));
280 }
281
282 overallMissLatency
283 .name(name() + ".overall_miss_latency")
284 .desc("number of overall miss cycles")
285 .flags(total | nozero | nonan)
286 ;
287 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
288 for (int i = 0; i < system->maxMasters(); i++) {
289 overallMissLatency.subname(i, system->getMasterName(i));
290 }
291
292 // access formulas
293 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
294 MemCmd cmd(access_idx);
295 const string &cstr = cmd.toString();
296
297 accesses[access_idx]
298 .name(name() + "." + cstr + "_accesses")
299 .desc("number of " + cstr + " accesses(hits+misses)")
300 .flags(total | nozero | nonan)
301 ;
302 accesses[access_idx] = hits[access_idx] + misses[access_idx];
303
304 for (int i = 0; i < system->maxMasters(); i++) {
305 accesses[access_idx].subname(i, system->getMasterName(i));
306 }
307 }
308
309 demandAccesses
310 .name(name() + ".demand_accesses")
311 .desc("number of demand (read+write) accesses")
312 .flags(total | nozero | nonan)
313 ;
314 demandAccesses = demandHits + demandMisses;
315 for (int i = 0; i < system->maxMasters(); i++) {
316 demandAccesses.subname(i, system->getMasterName(i));
317 }
318
319 overallAccesses
320 .name(name() + ".overall_accesses")
321 .desc("number of overall (read+write) accesses")
322 .flags(total | nozero | nonan)
323 ;
324 overallAccesses = overallHits + overallMisses;
325 for (int i = 0; i < system->maxMasters(); i++) {
326 overallAccesses.subname(i, system->getMasterName(i));
327 }
328
329 // miss rate formulas
330 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
331 MemCmd cmd(access_idx);
332 const string &cstr = cmd.toString();
333
334 missRate[access_idx]
335 .name(name() + "." + cstr + "_miss_rate")
336 .desc("miss rate for " + cstr + " accesses")
337 .flags(total | nozero | nonan)
338 ;
339 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
340
341 for (int i = 0; i < system->maxMasters(); i++) {
342 missRate[access_idx].subname(i, system->getMasterName(i));
343 }
344 }
345
346 demandMissRate
347 .name(name() + ".demand_miss_rate")
348 .desc("miss rate for demand accesses")
349 .flags(total | nozero | nonan)
350 ;
351 demandMissRate = demandMisses / demandAccesses;
352 for (int i = 0; i < system->maxMasters(); i++) {
353 demandMissRate.subname(i, system->getMasterName(i));
354 }
355
356 overallMissRate
357 .name(name() + ".overall_miss_rate")
358 .desc("miss rate for overall accesses")
359 .flags(total | nozero | nonan)
360 ;
361 overallMissRate = overallMisses / overallAccesses;
362 for (int i = 0; i < system->maxMasters(); i++) {
363 overallMissRate.subname(i, system->getMasterName(i));
364 }
365
366 // miss latency formulas
367 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
368 MemCmd cmd(access_idx);
369 const string &cstr = cmd.toString();
370
371 avgMissLatency[access_idx]
372 .name(name() + "." + cstr + "_avg_miss_latency")
373 .desc("average " + cstr + " miss latency")
374 .flags(total | nozero | nonan)
375 ;
376 avgMissLatency[access_idx] =
377 missLatency[access_idx] / misses[access_idx];
378
379 for (int i = 0; i < system->maxMasters(); i++) {
380 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
381 }
382 }
383
384 demandAvgMissLatency
385 .name(name() + ".demand_avg_miss_latency")
386 .desc("average overall miss latency")
387 .flags(total | nozero | nonan)
388 ;
389 demandAvgMissLatency = demandMissLatency / demandMisses;
390 for (int i = 0; i < system->maxMasters(); i++) {
391 demandAvgMissLatency.subname(i, system->getMasterName(i));
392 }
393
394 overallAvgMissLatency
395 .name(name() + ".overall_avg_miss_latency")
396 .desc("average overall miss latency")
397 .flags(total | nozero | nonan)
398 ;
399 overallAvgMissLatency = overallMissLatency / overallMisses;
400 for (int i = 0; i < system->maxMasters(); i++) {
401 overallAvgMissLatency.subname(i, system->getMasterName(i));
402 }
403
404 blocked_cycles.init(NUM_BLOCKED_CAUSES);
405 blocked_cycles
406 .name(name() + ".blocked_cycles")
407 .desc("number of cycles access was blocked")
408 .subname(Blocked_NoMSHRs, "no_mshrs")
409 .subname(Blocked_NoTargets, "no_targets")
410 ;
411
412
413 blocked_causes.init(NUM_BLOCKED_CAUSES);
414 blocked_causes
415 .name(name() + ".blocked")
416 .desc("number of cycles access was blocked")
417 .subname(Blocked_NoMSHRs, "no_mshrs")
418 .subname(Blocked_NoTargets, "no_targets")
419 ;
420
421 avg_blocked
422 .name(name() + ".avg_blocked_cycles")
423 .desc("average number of cycles each access was blocked")
424 .subname(Blocked_NoMSHRs, "no_mshrs")
425 .subname(Blocked_NoTargets, "no_targets")
426 ;
427
428 avg_blocked = blocked_cycles / blocked_causes;
429
430 fastWrites
431 .name(name() + ".fast_writes")
432 .desc("number of fast writes performed")
433 ;
434
435 cacheCopies
436 .name(name() + ".cache_copies")
437 .desc("number of cache copies performed")
438 ;
439
440 writebacks
441 .init(system->maxMasters())
442 .name(name() + ".writebacks")
443 .desc("number of writebacks")
444 .flags(total | nozero | nonan)
445 ;
446 for (int i = 0; i < system->maxMasters(); i++) {
447 writebacks.subname(i, system->getMasterName(i));
448 }
449
450 // MSHR statistics
451 // MSHR hit statistics
452 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
453 MemCmd cmd(access_idx);
454 const string &cstr = cmd.toString();
455
456 mshr_hits[access_idx]
457 .init(system->maxMasters())
458 .name(name() + "." + cstr + "_mshr_hits")
459 .desc("number of " + cstr + " MSHR hits")
460 .flags(total | nozero | nonan)
461 ;
462 for (int i = 0; i < system->maxMasters(); i++) {
463 mshr_hits[access_idx].subname(i, system->getMasterName(i));
464 }
465 }
466
467 demandMshrHits
468 .name(name() + ".demand_mshr_hits")
469 .desc("number of demand (read+write) MSHR hits")
470 .flags(total | nozero | nonan)
471 ;
472 demandMshrHits = SUM_DEMAND(mshr_hits);
473 for (int i = 0; i < system->maxMasters(); i++) {
474 demandMshrHits.subname(i, system->getMasterName(i));
475 }
476
477 overallMshrHits
478 .name(name() + ".overall_mshr_hits")
479 .desc("number of overall MSHR hits")
480 .flags(total | nozero | nonan)
481 ;
482 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
483 for (int i = 0; i < system->maxMasters(); i++) {
484 overallMshrHits.subname(i, system->getMasterName(i));
485 }
486
487 // MSHR miss statistics
488 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
489 MemCmd cmd(access_idx);
490 const string &cstr = cmd.toString();
491
492 mshr_misses[access_idx]
493 .init(system->maxMasters())
494 .name(name() + "." + cstr + "_mshr_misses")
495 .desc("number of " + cstr + " MSHR misses")
496 .flags(total | nozero | nonan)
497 ;
498 for (int i = 0; i < system->maxMasters(); i++) {
499 mshr_misses[access_idx].subname(i, system->getMasterName(i));
500 }
501 }
502
503 demandMshrMisses
504 .name(name() + ".demand_mshr_misses")
505 .desc("number of demand (read+write) MSHR misses")
506 .flags(total | nozero | nonan)
507 ;
508 demandMshrMisses = SUM_DEMAND(mshr_misses);
509 for (int i = 0; i < system->maxMasters(); i++) {
510 demandMshrMisses.subname(i, system->getMasterName(i));
511 }
512
513 overallMshrMisses
514 .name(name() + ".overall_mshr_misses")
515 .desc("number of overall MSHR misses")
516 .flags(total | nozero | nonan)
517 ;
518 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
519 for (int i = 0; i < system->maxMasters(); i++) {
520 overallMshrMisses.subname(i, system->getMasterName(i));
521 }
522
523 // MSHR miss latency statistics
524 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
525 MemCmd cmd(access_idx);
526 const string &cstr = cmd.toString();
527
528 mshr_miss_latency[access_idx]
529 .init(system->maxMasters())
530 .name(name() + "." + cstr + "_mshr_miss_latency")
531 .desc("number of " + cstr + " MSHR miss cycles")
532 .flags(total | nozero | nonan)
533 ;
534 for (int i = 0; i < system->maxMasters(); i++) {
535 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
536 }
537 }
538
539 demandMshrMissLatency
540 .name(name() + ".demand_mshr_miss_latency")
541 .desc("number of demand (read+write) MSHR miss cycles")
542 .flags(total | nozero | nonan)
543 ;
544 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
545 for (int i = 0; i < system->maxMasters(); i++) {
546 demandMshrMissLatency.subname(i, system->getMasterName(i));
547 }
548
549 overallMshrMissLatency
550 .name(name() + ".overall_mshr_miss_latency")
551 .desc("number of overall MSHR miss cycles")
552 .flags(total | nozero | nonan)
553 ;
554 overallMshrMissLatency =
555 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
556 for (int i = 0; i < system->maxMasters(); i++) {
557 overallMshrMissLatency.subname(i, system->getMasterName(i));
558 }
559
560 // MSHR uncacheable statistics
561 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
562 MemCmd cmd(access_idx);
563 const string &cstr = cmd.toString();
564
565 mshr_uncacheable[access_idx]
566 .init(system->maxMasters())
567 .name(name() + "." + cstr + "_mshr_uncacheable")
568 .desc("number of " + cstr + " MSHR uncacheable")
569 .flags(total | nozero | nonan)
570 ;
571 for (int i = 0; i < system->maxMasters(); i++) {
572 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
573 }
574 }
575
576 overallMshrUncacheable
577 .name(name() + ".overall_mshr_uncacheable_misses")
578 .desc("number of overall MSHR uncacheable misses")
579 .flags(total | nozero | nonan)
580 ;
581 overallMshrUncacheable =
582 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
583 for (int i = 0; i < system->maxMasters(); i++) {
584 overallMshrUncacheable.subname(i, system->getMasterName(i));
585 }
586
587 // MSHR miss latency statistics
588 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
589 MemCmd cmd(access_idx);
590 const string &cstr = cmd.toString();
591
592 mshr_uncacheable_lat[access_idx]
593 .init(system->maxMasters())
594 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
595 .desc("number of " + cstr + " MSHR uncacheable cycles")
596 .flags(total | nozero | nonan)
597 ;
598 for (int i = 0; i < system->maxMasters(); i++) {
599 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
600 }
601 }
602
603 overallMshrUncacheableLatency
604 .name(name() + ".overall_mshr_uncacheable_latency")
605 .desc("number of overall MSHR uncacheable cycles")
606 .flags(total | nozero | nonan)
607 ;
608 overallMshrUncacheableLatency =
609 SUM_DEMAND(mshr_uncacheable_lat) +
610 SUM_NON_DEMAND(mshr_uncacheable_lat);
611 for (int i = 0; i < system->maxMasters(); i++) {
612 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
613 }
614
615#if 0
616 // MSHR access formulas
617 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
618 MemCmd cmd(access_idx);
619 const string &cstr = cmd.toString();
620
621 mshrAccesses[access_idx]
622 .name(name() + "." + cstr + "_mshr_accesses")
623 .desc("number of " + cstr + " mshr accesses(hits+misses)")
624 .flags(total | nozero | nonan)
625 ;
626 mshrAccesses[access_idx] =
627 mshr_hits[access_idx] + mshr_misses[access_idx]
628 + mshr_uncacheable[access_idx];
629 }
630
631 demandMshrAccesses
632 .name(name() + ".demand_mshr_accesses")
633 .desc("number of demand (read+write) mshr accesses")
634 .flags(total | nozero | nonan)
635 ;
636 demandMshrAccesses = demandMshrHits + demandMshrMisses;
637
638 overallMshrAccesses
639 .name(name() + ".overall_mshr_accesses")
640 .desc("number of overall (read+write) mshr accesses")
641 .flags(total | nozero | nonan)
642 ;
643 overallMshrAccesses = overallMshrHits + overallMshrMisses
644 + overallMshrUncacheable;
645#endif
646
647 // MSHR miss rate formulas
648 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
649 MemCmd cmd(access_idx);
650 const string &cstr = cmd.toString();
651
652 mshrMissRate[access_idx]
653 .name(name() + "." + cstr + "_mshr_miss_rate")
654 .desc("mshr miss rate for " + cstr + " accesses")
655 .flags(total | nozero | nonan)
656 ;
657 mshrMissRate[access_idx] =
658 mshr_misses[access_idx] / accesses[access_idx];
659
660 for (int i = 0; i < system->maxMasters(); i++) {
661 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
662 }
663 }
664
665 demandMshrMissRate
666 .name(name() + ".demand_mshr_miss_rate")
667 .desc("mshr miss rate for demand accesses")
668 .flags(total | nozero | nonan)
669 ;
670 demandMshrMissRate = demandMshrMisses / demandAccesses;
671 for (int i = 0; i < system->maxMasters(); i++) {
672 demandMshrMissRate.subname(i, system->getMasterName(i));
673 }
674
675 overallMshrMissRate
676 .name(name() + ".overall_mshr_miss_rate")
677 .desc("mshr miss rate for overall accesses")
678 .flags(total | nozero | nonan)
679 ;
680 overallMshrMissRate = overallMshrMisses / overallAccesses;
681 for (int i = 0; i < system->maxMasters(); i++) {
682 overallMshrMissRate.subname(i, system->getMasterName(i));
683 }
684
685 // mshrMiss latency formulas
686 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
687 MemCmd cmd(access_idx);
688 const string &cstr = cmd.toString();
689
690 avgMshrMissLatency[access_idx]
691 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
692 .desc("average " + cstr + " mshr miss latency")
693 .flags(total | nozero | nonan)
694 ;
695 avgMshrMissLatency[access_idx] =
696 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
697
698 for (int i = 0; i < system->maxMasters(); i++) {
699 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
700 }
701 }
702
703 demandAvgMshrMissLatency
704 .name(name() + ".demand_avg_mshr_miss_latency")
705 .desc("average overall mshr miss latency")
706 .flags(total | nozero | nonan)
707 ;
708 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
709 for (int i = 0; i < system->maxMasters(); i++) {
710 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
711 }
712
713 overallAvgMshrMissLatency
714 .name(name() + ".overall_avg_mshr_miss_latency")
715 .desc("average overall mshr miss latency")
716 .flags(total | nozero | nonan)
717 ;
718 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
719 for (int i = 0; i < system->maxMasters(); i++) {
720 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
721 }
722
723 // mshrUncacheable latency formulas
724 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
725 MemCmd cmd(access_idx);
726 const string &cstr = cmd.toString();
727
728 avgMshrUncacheableLatency[access_idx]
729 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
730 .desc("average " + cstr + " mshr uncacheable latency")
731 .flags(total | nozero | nonan)
732 ;
733 avgMshrUncacheableLatency[access_idx] =
734 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
735
736 for (int i = 0; i < system->maxMasters(); i++) {
737 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
738 }
739 }
740
741 overallAvgMshrUncacheableLatency
742 .name(name() + ".overall_avg_mshr_uncacheable_latency")
743 .desc("average overall mshr uncacheable latency")
744 .flags(total | nozero | nonan)
745 ;
746 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
747 for (int i = 0; i < system->maxMasters(); i++) {
748 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
749 }
750
751 mshr_cap_events
752 .init(system->maxMasters())
753 .name(name() + ".mshr_cap_events")
754 .desc("number of times MSHR cap was activated")
755 .flags(total | nozero | nonan)
756 ;
757 for (int i = 0; i < system->maxMasters(); i++) {
758 mshr_cap_events.subname(i, system->getMasterName(i));
759 }
760
761 //software prefetching stats
762 soft_prefetch_mshr_full
763 .init(system->maxMasters())
764 .name(name() + ".soft_prefetch_mshr_full")
765 .desc("number of mshr full events for SW prefetching instrutions")
766 .flags(total | nozero | nonan)
767 ;
768 for (int i = 0; i < system->maxMasters(); i++) {
769 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
770 }
771
772 mshr_no_allocate_misses
773 .name(name() +".no_allocate_misses")
774 .desc("Number of misses that were no-allocate")
775 ;
776
777}
778
779unsigned int
780BaseCache::drain(DrainManager *dm)
781{
782 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
783 mshrQueue.drain(dm) + writeBuffer.drain(dm);
784
785 // Set status
786 if (count != 0) {
787 setDrainState(Drainable::Draining);
788 DPRINTF(Drain, "Cache not drained\n");
789 return count;
790 }
791
792 setDrainState(Drainable::Drained);
793 return 0;
794}
795
796BaseCache *
797BaseCacheParams::create()
798{
799 assert(tags);
800
801 return new Cache(this);
802}