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