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 BaseCacheParams *p, unsigned blk_size)
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),
71 mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve),
72 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000),
73 blkSize(blk_size),
74 lookupLatency(p->hit_latency),
75 forwardLatency(p->hit_latency),
76 fillLatency(p->response_latency),
77 responseLatency(p->response_latency),
78 numTarget(p->tgts_per_mshr),
79 forwardSnoops(true),
80 isReadOnly(p->is_read_only),
81 blocked(0),
82 order(0),
83 noTargetMSHR(NULL),
84 missCount(p->max_miss_count),
85 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
86 system(p->system)
87{
88 // forward snoops is overridden in init() once we can query
89 // whether the connected master is actually snooping or not
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 forwardSnoops = cpuSidePort->isSnooping();
136}
137
138BaseMasterPort &
139BaseCache::getMasterPort(const std::string &if_name, PortID idx)
140{
141 if (if_name == "mem_side") {
142 return *memSidePort;
143 } else {
144 return MemObject::getMasterPort(if_name, idx);
145 }
146}
147
148BaseSlavePort &
149BaseCache::getSlavePort(const std::string &if_name, PortID idx)
150{
151 if (if_name == "cpu_side") {
152 return *cpuSidePort;
153 } else {
154 return MemObject::getSlavePort(if_name, idx);
155 }
156}
157
158bool
159BaseCache::inRange(Addr addr) const
160{
161 for (const auto& r : addrRanges) {
162 if (r.contains(addr)) {
163 return true;
164 }
165 }
166 return false;
167}
168
169void
170BaseCache::regStats()
171{
172 using namespace Stats;
173
174 // Hit statistics
175 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
176 MemCmd cmd(access_idx);
177 const string &cstr = cmd.toString();
178
179 hits[access_idx]
180 .init(system->maxMasters())
181 .name(name() + "." + cstr + "_hits")
182 .desc("number of " + cstr + " hits")
183 .flags(total | nozero | nonan)
184 ;
185 for (int i = 0; i < system->maxMasters(); i++) {
186 hits[access_idx].subname(i, system->getMasterName(i));
187 }
188 }
189
190// These macros make it easier to sum the right subset of commands and
191// to change the subset of commands that are considered "demand" vs
192// "non-demand"
193#define SUM_DEMAND(s) \
194 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + \
195 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
196
197// should writebacks be included here? prior code was inconsistent...
198#define SUM_NON_DEMAND(s) \
199 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
200
201 demandHits
202 .name(name() + ".demand_hits")
203 .desc("number of demand (read+write) hits")
204 .flags(total | nozero | nonan)
205 ;
206 demandHits = SUM_DEMAND(hits);
207 for (int i = 0; i < system->maxMasters(); i++) {
208 demandHits.subname(i, system->getMasterName(i));
209 }
210
211 overallHits
212 .name(name() + ".overall_hits")
213 .desc("number of overall hits")
214 .flags(total | nozero | nonan)
215 ;
216 overallHits = demandHits + SUM_NON_DEMAND(hits);
217 for (int i = 0; i < system->maxMasters(); i++) {
218 overallHits.subname(i, system->getMasterName(i));
219 }
220
221 // Miss statistics
222 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
223 MemCmd cmd(access_idx);
224 const string &cstr = cmd.toString();
225
226 misses[access_idx]
227 .init(system->maxMasters())
228 .name(name() + "." + cstr + "_misses")
229 .desc("number of " + cstr + " misses")
230 .flags(total | nozero | nonan)
231 ;
232 for (int i = 0; i < system->maxMasters(); i++) {
233 misses[access_idx].subname(i, system->getMasterName(i));
234 }
235 }
236
237 demandMisses
238 .name(name() + ".demand_misses")
239 .desc("number of demand (read+write) misses")
240 .flags(total | nozero | nonan)
241 ;
242 demandMisses = SUM_DEMAND(misses);
243 for (int i = 0; i < system->maxMasters(); i++) {
244 demandMisses.subname(i, system->getMasterName(i));
245 }
246
247 overallMisses
248 .name(name() + ".overall_misses")
249 .desc("number of overall misses")
250 .flags(total | nozero | nonan)
251 ;
252 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
253 for (int i = 0; i < system->maxMasters(); i++) {
254 overallMisses.subname(i, system->getMasterName(i));
255 }
256
257 // Miss latency statistics
258 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
259 MemCmd cmd(access_idx);
260 const string &cstr = cmd.toString();
261
262 missLatency[access_idx]
263 .init(system->maxMasters())
264 .name(name() + "." + cstr + "_miss_latency")
265 .desc("number of " + cstr + " miss cycles")
266 .flags(total | nozero | nonan)
267 ;
268 for (int i = 0; i < system->maxMasters(); i++) {
269 missLatency[access_idx].subname(i, system->getMasterName(i));
270 }
271 }
272
273 demandMissLatency
274 .name(name() + ".demand_miss_latency")
275 .desc("number of demand (read+write) miss cycles")
276 .flags(total | nozero | nonan)
277 ;
278 demandMissLatency = SUM_DEMAND(missLatency);
279 for (int i = 0; i < system->maxMasters(); i++) {
280 demandMissLatency.subname(i, system->getMasterName(i));
281 }
282
283 overallMissLatency
284 .name(name() + ".overall_miss_latency")
285 .desc("number of overall miss cycles")
286 .flags(total | nozero | nonan)
287 ;
288 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
289 for (int i = 0; i < system->maxMasters(); i++) {
290 overallMissLatency.subname(i, system->getMasterName(i));
291 }
292
293 // access formulas
294 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
295 MemCmd cmd(access_idx);
296 const string &cstr = cmd.toString();
297
298 accesses[access_idx]
299 .name(name() + "." + cstr + "_accesses")
300 .desc("number of " + cstr + " accesses(hits+misses)")
301 .flags(total | nozero | nonan)
302 ;
303 accesses[access_idx] = hits[access_idx] + misses[access_idx];
304
305 for (int i = 0; i < system->maxMasters(); i++) {
306 accesses[access_idx].subname(i, system->getMasterName(i));
307 }
308 }
309
310 demandAccesses
311 .name(name() + ".demand_accesses")
312 .desc("number of demand (read+write) accesses")
313 .flags(total | nozero | nonan)
314 ;
315 demandAccesses = demandHits + demandMisses;
316 for (int i = 0; i < system->maxMasters(); i++) {
317 demandAccesses.subname(i, system->getMasterName(i));
318 }
319
320 overallAccesses
321 .name(name() + ".overall_accesses")
322 .desc("number of overall (read+write) accesses")
323 .flags(total | nozero | nonan)
324 ;
325 overallAccesses = overallHits + overallMisses;
326 for (int i = 0; i < system->maxMasters(); i++) {
327 overallAccesses.subname(i, system->getMasterName(i));
328 }
329
330 // miss rate formulas
331 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
332 MemCmd cmd(access_idx);
333 const string &cstr = cmd.toString();
334
335 missRate[access_idx]
336 .name(name() + "." + cstr + "_miss_rate")
337 .desc("miss rate for " + cstr + " accesses")
338 .flags(total | nozero | nonan)
339 ;
340 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
341
342 for (int i = 0; i < system->maxMasters(); i++) {
343 missRate[access_idx].subname(i, system->getMasterName(i));
344 }
345 }
346
347 demandMissRate
348 .name(name() + ".demand_miss_rate")
349 .desc("miss rate for demand accesses")
350 .flags(total | nozero | nonan)
351 ;
352 demandMissRate = demandMisses / demandAccesses;
353 for (int i = 0; i < system->maxMasters(); i++) {
354 demandMissRate.subname(i, system->getMasterName(i));
355 }
356
357 overallMissRate
358 .name(name() + ".overall_miss_rate")
359 .desc("miss rate for overall accesses")
360 .flags(total | nozero | nonan)
361 ;
362 overallMissRate = overallMisses / overallAccesses;
363 for (int i = 0; i < system->maxMasters(); i++) {
364 overallMissRate.subname(i, system->getMasterName(i));
365 }
366
367 // miss latency formulas
368 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
369 MemCmd cmd(access_idx);
370 const string &cstr = cmd.toString();
371
372 avgMissLatency[access_idx]
373 .name(name() + "." + cstr + "_avg_miss_latency")
374 .desc("average " + cstr + " miss latency")
375 .flags(total | nozero | nonan)
376 ;
377 avgMissLatency[access_idx] =
378 missLatency[access_idx] / misses[access_idx];
379
380 for (int i = 0; i < system->maxMasters(); i++) {
381 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
382 }
383 }
384
385 demandAvgMissLatency
386 .name(name() + ".demand_avg_miss_latency")
387 .desc("average overall miss latency")
388 .flags(total | nozero | nonan)
389 ;
390 demandAvgMissLatency = demandMissLatency / demandMisses;
391 for (int i = 0; i < system->maxMasters(); i++) {
392 demandAvgMissLatency.subname(i, system->getMasterName(i));
393 }
394
395 overallAvgMissLatency
396 .name(name() + ".overall_avg_miss_latency")
397 .desc("average overall miss latency")
398 .flags(total | nozero | nonan)
399 ;
400 overallAvgMissLatency = overallMissLatency / overallMisses;
401 for (int i = 0; i < system->maxMasters(); i++) {
402 overallAvgMissLatency.subname(i, system->getMasterName(i));
403 }
404
405 blocked_cycles.init(NUM_BLOCKED_CAUSES);
406 blocked_cycles
407 .name(name() + ".blocked_cycles")
408 .desc("number of cycles access was blocked")
409 .subname(Blocked_NoMSHRs, "no_mshrs")
410 .subname(Blocked_NoTargets, "no_targets")
411 ;
412
413
414 blocked_causes.init(NUM_BLOCKED_CAUSES);
415 blocked_causes
416 .name(name() + ".blocked")
417 .desc("number of cycles access was blocked")
418 .subname(Blocked_NoMSHRs, "no_mshrs")
419 .subname(Blocked_NoTargets, "no_targets")
420 ;
421
422 avg_blocked
423 .name(name() + ".avg_blocked_cycles")
424 .desc("average number of cycles each access was blocked")
425 .subname(Blocked_NoMSHRs, "no_mshrs")
426 .subname(Blocked_NoTargets, "no_targets")
427 ;
428
429 avg_blocked = blocked_cycles / blocked_causes;
430
431 fastWrites
432 .name(name() + ".fast_writes")
433 .desc("number of fast writes performed")
434 ;
435
436 cacheCopies
437 .name(name() + ".cache_copies")
438 .desc("number of cache copies performed")
439 ;
440
441 writebacks
442 .init(system->maxMasters())
443 .name(name() + ".writebacks")
444 .desc("number of writebacks")
445 .flags(total | nozero | nonan)
446 ;
447 for (int i = 0; i < system->maxMasters(); i++) {
448 writebacks.subname(i, system->getMasterName(i));
449 }
450
451 // MSHR statistics
452 // MSHR hit statistics
453 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
454 MemCmd cmd(access_idx);
455 const string &cstr = cmd.toString();
456
457 mshr_hits[access_idx]
458 .init(system->maxMasters())
459 .name(name() + "." + cstr + "_mshr_hits")
460 .desc("number of " + cstr + " MSHR hits")
461 .flags(total | nozero | nonan)
462 ;
463 for (int i = 0; i < system->maxMasters(); i++) {
464 mshr_hits[access_idx].subname(i, system->getMasterName(i));
465 }
466 }
467
468 demandMshrHits
469 .name(name() + ".demand_mshr_hits")
470 .desc("number of demand (read+write) MSHR hits")
471 .flags(total | nozero | nonan)
472 ;
473 demandMshrHits = SUM_DEMAND(mshr_hits);
474 for (int i = 0; i < system->maxMasters(); i++) {
475 demandMshrHits.subname(i, system->getMasterName(i));
476 }
477
478 overallMshrHits
479 .name(name() + ".overall_mshr_hits")
480 .desc("number of overall MSHR hits")
481 .flags(total | nozero | nonan)
482 ;
483 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
484 for (int i = 0; i < system->maxMasters(); i++) {
485 overallMshrHits.subname(i, system->getMasterName(i));
486 }
487
488 // MSHR miss statistics
489 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
490 MemCmd cmd(access_idx);
491 const string &cstr = cmd.toString();
492
493 mshr_misses[access_idx]
494 .init(system->maxMasters())
495 .name(name() + "." + cstr + "_mshr_misses")
496 .desc("number of " + cstr + " MSHR misses")
497 .flags(total | nozero | nonan)
498 ;
499 for (int i = 0; i < system->maxMasters(); i++) {
500 mshr_misses[access_idx].subname(i, system->getMasterName(i));
501 }
502 }
503
504 demandMshrMisses
505 .name(name() + ".demand_mshr_misses")
506 .desc("number of demand (read+write) MSHR misses")
507 .flags(total | nozero | nonan)
508 ;
509 demandMshrMisses = SUM_DEMAND(mshr_misses);
510 for (int i = 0; i < system->maxMasters(); i++) {
511 demandMshrMisses.subname(i, system->getMasterName(i));
512 }
513
514 overallMshrMisses
515 .name(name() + ".overall_mshr_misses")
516 .desc("number of overall MSHR misses")
517 .flags(total | nozero | nonan)
518 ;
519 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
520 for (int i = 0; i < system->maxMasters(); i++) {
521 overallMshrMisses.subname(i, system->getMasterName(i));
522 }
523
524 // MSHR miss latency statistics
525 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
526 MemCmd cmd(access_idx);
527 const string &cstr = cmd.toString();
528
529 mshr_miss_latency[access_idx]
530 .init(system->maxMasters())
531 .name(name() + "." + cstr + "_mshr_miss_latency")
532 .desc("number of " + cstr + " MSHR miss cycles")
533 .flags(total | nozero | nonan)
534 ;
535 for (int i = 0; i < system->maxMasters(); i++) {
536 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
537 }
538 }
539
540 demandMshrMissLatency
541 .name(name() + ".demand_mshr_miss_latency")
542 .desc("number of demand (read+write) MSHR miss cycles")
543 .flags(total | nozero | nonan)
544 ;
545 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
546 for (int i = 0; i < system->maxMasters(); i++) {
547 demandMshrMissLatency.subname(i, system->getMasterName(i));
548 }
549
550 overallMshrMissLatency
551 .name(name() + ".overall_mshr_miss_latency")
552 .desc("number of overall MSHR miss cycles")
553 .flags(total | nozero | nonan)
554 ;
555 overallMshrMissLatency =
556 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
557 for (int i = 0; i < system->maxMasters(); i++) {
558 overallMshrMissLatency.subname(i, system->getMasterName(i));
559 }
560
561 // MSHR uncacheable statistics
562 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
563 MemCmd cmd(access_idx);
564 const string &cstr = cmd.toString();
565
566 mshr_uncacheable[access_idx]
567 .init(system->maxMasters())
568 .name(name() + "." + cstr + "_mshr_uncacheable")
569 .desc("number of " + cstr + " MSHR uncacheable")
570 .flags(total | nozero | nonan)
571 ;
572 for (int i = 0; i < system->maxMasters(); i++) {
573 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
574 }
575 }
576
577 overallMshrUncacheable
578 .name(name() + ".overall_mshr_uncacheable_misses")
579 .desc("number of overall MSHR uncacheable misses")
580 .flags(total | nozero | nonan)
581 ;
582 overallMshrUncacheable =
583 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
584 for (int i = 0; i < system->maxMasters(); i++) {
585 overallMshrUncacheable.subname(i, system->getMasterName(i));
586 }
587
588 // MSHR miss latency statistics
589 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
590 MemCmd cmd(access_idx);
591 const string &cstr = cmd.toString();
592
593 mshr_uncacheable_lat[access_idx]
594 .init(system->maxMasters())
595 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
596 .desc("number of " + cstr + " MSHR uncacheable cycles")
597 .flags(total | nozero | nonan)
598 ;
599 for (int i = 0; i < system->maxMasters(); i++) {
600 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
601 }
602 }
603
604 overallMshrUncacheableLatency
605 .name(name() + ".overall_mshr_uncacheable_latency")
606 .desc("number of overall MSHR uncacheable cycles")
607 .flags(total | nozero | nonan)
608 ;
609 overallMshrUncacheableLatency =
610 SUM_DEMAND(mshr_uncacheable_lat) +
611 SUM_NON_DEMAND(mshr_uncacheable_lat);
612 for (int i = 0; i < system->maxMasters(); i++) {
613 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
614 }
615
616#if 0
617 // MSHR access formulas
618 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
619 MemCmd cmd(access_idx);
620 const string &cstr = cmd.toString();
621
622 mshrAccesses[access_idx]
623 .name(name() + "." + cstr + "_mshr_accesses")
624 .desc("number of " + cstr + " mshr accesses(hits+misses)")
625 .flags(total | nozero | nonan)
626 ;
627 mshrAccesses[access_idx] =
628 mshr_hits[access_idx] + mshr_misses[access_idx]
629 + mshr_uncacheable[access_idx];
630 }
631
632 demandMshrAccesses
633 .name(name() + ".demand_mshr_accesses")
634 .desc("number of demand (read+write) mshr accesses")
635 .flags(total | nozero | nonan)
636 ;
637 demandMshrAccesses = demandMshrHits + demandMshrMisses;
638
639 overallMshrAccesses
640 .name(name() + ".overall_mshr_accesses")
641 .desc("number of overall (read+write) mshr accesses")
642 .flags(total | nozero | nonan)
643 ;
644 overallMshrAccesses = overallMshrHits + overallMshrMisses
645 + overallMshrUncacheable;
646#endif
647
648 // MSHR miss rate formulas
649 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
650 MemCmd cmd(access_idx);
651 const string &cstr = cmd.toString();
652
653 mshrMissRate[access_idx]
654 .name(name() + "." + cstr + "_mshr_miss_rate")
655 .desc("mshr miss rate for " + cstr + " accesses")
656 .flags(total | nozero | nonan)
657 ;
658 mshrMissRate[access_idx] =
659 mshr_misses[access_idx] / accesses[access_idx];
660
661 for (int i = 0; i < system->maxMasters(); i++) {
662 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
663 }
664 }
665
666 demandMshrMissRate
667 .name(name() + ".demand_mshr_miss_rate")
668 .desc("mshr miss rate for demand accesses")
669 .flags(total | nozero | nonan)
670 ;
671 demandMshrMissRate = demandMshrMisses / demandAccesses;
672 for (int i = 0; i < system->maxMasters(); i++) {
673 demandMshrMissRate.subname(i, system->getMasterName(i));
674 }
675
676 overallMshrMissRate
677 .name(name() + ".overall_mshr_miss_rate")
678 .desc("mshr miss rate for overall accesses")
679 .flags(total | nozero | nonan)
680 ;
681 overallMshrMissRate = overallMshrMisses / overallAccesses;
682 for (int i = 0; i < system->maxMasters(); i++) {
683 overallMshrMissRate.subname(i, system->getMasterName(i));
684 }
685
686 // mshrMiss latency formulas
687 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
688 MemCmd cmd(access_idx);
689 const string &cstr = cmd.toString();
690
691 avgMshrMissLatency[access_idx]
692 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
693 .desc("average " + cstr + " mshr miss latency")
694 .flags(total | nozero | nonan)
695 ;
696 avgMshrMissLatency[access_idx] =
697 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
698
699 for (int i = 0; i < system->maxMasters(); i++) {
700 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
701 }
702 }
703
704 demandAvgMshrMissLatency
705 .name(name() + ".demand_avg_mshr_miss_latency")
706 .desc("average overall mshr miss latency")
707 .flags(total | nozero | nonan)
708 ;
709 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
710 for (int i = 0; i < system->maxMasters(); i++) {
711 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
712 }
713
714 overallAvgMshrMissLatency
715 .name(name() + ".overall_avg_mshr_miss_latency")
716 .desc("average overall mshr miss latency")
717 .flags(total | nozero | nonan)
718 ;
719 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
720 for (int i = 0; i < system->maxMasters(); i++) {
721 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
722 }
723
724 // mshrUncacheable latency formulas
725 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
726 MemCmd cmd(access_idx);
727 const string &cstr = cmd.toString();
728
729 avgMshrUncacheableLatency[access_idx]
730 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
731 .desc("average " + cstr + " mshr uncacheable latency")
732 .flags(total | nozero | nonan)
733 ;
734 avgMshrUncacheableLatency[access_idx] =
735 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
736
737 for (int i = 0; i < system->maxMasters(); i++) {
738 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
739 }
740 }
741
742 overallAvgMshrUncacheableLatency
743 .name(name() + ".overall_avg_mshr_uncacheable_latency")
744 .desc("average overall mshr uncacheable latency")
745 .flags(total | nozero | nonan)
746 ;
747 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
748 for (int i = 0; i < system->maxMasters(); i++) {
749 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
750 }
751
752 mshr_cap_events
753 .init(system->maxMasters())
754 .name(name() + ".mshr_cap_events")
755 .desc("number of times MSHR cap was activated")
756 .flags(total | nozero | nonan)
757 ;
758 for (int i = 0; i < system->maxMasters(); i++) {
759 mshr_cap_events.subname(i, system->getMasterName(i));
760 }
761
762 //software prefetching stats
763 soft_prefetch_mshr_full
764 .init(system->maxMasters())
765 .name(name() + ".soft_prefetch_mshr_full")
766 .desc("number of mshr full events for SW prefetching instrutions")
767 .flags(total | nozero | nonan)
768 ;
769 for (int i = 0; i < system->maxMasters(); i++) {
770 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
771 }
772
773 mshr_no_allocate_misses
774 .name(name() +".no_allocate_misses")
775 .desc("Number of misses that were no-allocate")
776 ;
777
778}