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