2 * Copyright (c) 2012-2013 ARM Limited
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.
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
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.
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.
40 * Authors: Erik Hallnor
45 * Definition of BaseCache functions.
48 #include "mem/cache/base.hh"
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"
61 BaseCache::CacheSlavePort::CacheSlavePort(const std::string
&_name
,
63 const std::string
&_label
)
64 : QueuedSlavePort(_name
, _cache
, queue
), queue(*_cache
, *this, _label
),
65 blocked(false), mustSendRetry(false), sendRetryEvent(this)
69 BaseCache::BaseCache(const BaseCacheParams
*p
, unsigned blk_size
)
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
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
),
81 isReadOnly(p
->is_read_only
),
84 noTargetMSHR(nullptr),
85 missCount(p
->max_miss_count
),
86 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
89 // the MSHR queue has no reserve entries as we check the MSHR
90 // queue on every single allocation, whereas the write queue has
91 // as many reserve entries as we have MSHRs, since every MSHR may
92 // eventually require a writeback, and we do not check the write
93 // buffer before committing to an MSHR
95 // forward snoops is overridden in init() once we can query
96 // whether the connected master is actually snooping or not
100 BaseCache::CacheSlavePort::setBlocked()
103 DPRINTF(CachePort
, "Port is blocking new requests\n");
105 // if we already scheduled a retry in this cycle, but it has not yet
106 // happened, cancel it
107 if (sendRetryEvent
.scheduled()) {
108 owner
.deschedule(sendRetryEvent
);
109 DPRINTF(CachePort
, "Port descheduled retry\n");
110 mustSendRetry
= true;
115 BaseCache::CacheSlavePort::clearBlocked()
118 DPRINTF(CachePort
, "Port is accepting new requests\n");
121 // @TODO: need to find a better time (next cycle?)
122 owner
.schedule(sendRetryEvent
, curTick() + 1);
127 BaseCache::CacheSlavePort::processSendRetry()
129 DPRINTF(CachePort
, "Port is sending retry\n");
131 // reset the flag and call retry
132 mustSendRetry
= false;
139 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
140 fatal("Cache ports on %s are not connected\n", name());
141 cpuSidePort
->sendRangeChange();
142 forwardSnoops
= cpuSidePort
->isSnooping();
146 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
148 if (if_name
== "mem_side") {
151 return MemObject::getMasterPort(if_name
, idx
);
156 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
158 if (if_name
== "cpu_side") {
161 return MemObject::getSlavePort(if_name
, idx
);
166 BaseCache::inRange(Addr addr
) const
168 for (const auto& r
: addrRanges
) {
169 if (r
.contains(addr
)) {
177 BaseCache::regStats()
179 MemObject::regStats();
181 using namespace Stats
;
184 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
185 MemCmd
cmd(access_idx
);
186 const string
&cstr
= cmd
.toString();
189 .init(system
->maxMasters())
190 .name(name() + "." + cstr
+ "_hits")
191 .desc("number of " + cstr
+ " hits")
192 .flags(total
| nozero
| nonan
)
194 for (int i
= 0; i
< system
->maxMasters(); i
++) {
195 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
199 // These macros make it easier to sum the right subset of commands and
200 // to change the subset of commands that are considered "demand" vs
202 #define SUM_DEMAND(s) \
203 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::WriteLineReq] + \
204 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
206 // should writebacks be included here? prior code was inconsistent...
207 #define SUM_NON_DEMAND(s) \
208 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
211 .name(name() + ".demand_hits")
212 .desc("number of demand (read+write) hits")
213 .flags(total
| nozero
| nonan
)
215 demandHits
= SUM_DEMAND(hits
);
216 for (int i
= 0; i
< system
->maxMasters(); i
++) {
217 demandHits
.subname(i
, system
->getMasterName(i
));
221 .name(name() + ".overall_hits")
222 .desc("number of overall hits")
223 .flags(total
| nozero
| nonan
)
225 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
226 for (int i
= 0; i
< system
->maxMasters(); i
++) {
227 overallHits
.subname(i
, system
->getMasterName(i
));
231 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
232 MemCmd
cmd(access_idx
);
233 const string
&cstr
= cmd
.toString();
236 .init(system
->maxMasters())
237 .name(name() + "." + cstr
+ "_misses")
238 .desc("number of " + cstr
+ " misses")
239 .flags(total
| nozero
| nonan
)
241 for (int i
= 0; i
< system
->maxMasters(); i
++) {
242 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
247 .name(name() + ".demand_misses")
248 .desc("number of demand (read+write) misses")
249 .flags(total
| nozero
| nonan
)
251 demandMisses
= SUM_DEMAND(misses
);
252 for (int i
= 0; i
< system
->maxMasters(); i
++) {
253 demandMisses
.subname(i
, system
->getMasterName(i
));
257 .name(name() + ".overall_misses")
258 .desc("number of overall misses")
259 .flags(total
| nozero
| nonan
)
261 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
262 for (int i
= 0; i
< system
->maxMasters(); i
++) {
263 overallMisses
.subname(i
, system
->getMasterName(i
));
266 // Miss latency statistics
267 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
268 MemCmd
cmd(access_idx
);
269 const string
&cstr
= cmd
.toString();
271 missLatency
[access_idx
]
272 .init(system
->maxMasters())
273 .name(name() + "." + cstr
+ "_miss_latency")
274 .desc("number of " + cstr
+ " miss cycles")
275 .flags(total
| nozero
| nonan
)
277 for (int i
= 0; i
< system
->maxMasters(); i
++) {
278 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
283 .name(name() + ".demand_miss_latency")
284 .desc("number of demand (read+write) miss cycles")
285 .flags(total
| nozero
| nonan
)
287 demandMissLatency
= SUM_DEMAND(missLatency
);
288 for (int i
= 0; i
< system
->maxMasters(); i
++) {
289 demandMissLatency
.subname(i
, system
->getMasterName(i
));
293 .name(name() + ".overall_miss_latency")
294 .desc("number of overall miss cycles")
295 .flags(total
| nozero
| nonan
)
297 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
298 for (int i
= 0; i
< system
->maxMasters(); i
++) {
299 overallMissLatency
.subname(i
, system
->getMasterName(i
));
303 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
304 MemCmd
cmd(access_idx
);
305 const string
&cstr
= cmd
.toString();
308 .name(name() + "." + cstr
+ "_accesses")
309 .desc("number of " + cstr
+ " accesses(hits+misses)")
310 .flags(total
| nozero
| nonan
)
312 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
314 for (int i
= 0; i
< system
->maxMasters(); i
++) {
315 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
320 .name(name() + ".demand_accesses")
321 .desc("number of demand (read+write) accesses")
322 .flags(total
| nozero
| nonan
)
324 demandAccesses
= demandHits
+ demandMisses
;
325 for (int i
= 0; i
< system
->maxMasters(); i
++) {
326 demandAccesses
.subname(i
, system
->getMasterName(i
));
330 .name(name() + ".overall_accesses")
331 .desc("number of overall (read+write) accesses")
332 .flags(total
| nozero
| nonan
)
334 overallAccesses
= overallHits
+ overallMisses
;
335 for (int i
= 0; i
< system
->maxMasters(); i
++) {
336 overallAccesses
.subname(i
, system
->getMasterName(i
));
339 // miss rate formulas
340 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
341 MemCmd
cmd(access_idx
);
342 const string
&cstr
= cmd
.toString();
345 .name(name() + "." + cstr
+ "_miss_rate")
346 .desc("miss rate for " + cstr
+ " accesses")
347 .flags(total
| nozero
| nonan
)
349 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
351 for (int i
= 0; i
< system
->maxMasters(); i
++) {
352 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
357 .name(name() + ".demand_miss_rate")
358 .desc("miss rate for demand accesses")
359 .flags(total
| nozero
| nonan
)
361 demandMissRate
= demandMisses
/ demandAccesses
;
362 for (int i
= 0; i
< system
->maxMasters(); i
++) {
363 demandMissRate
.subname(i
, system
->getMasterName(i
));
367 .name(name() + ".overall_miss_rate")
368 .desc("miss rate for overall accesses")
369 .flags(total
| nozero
| nonan
)
371 overallMissRate
= overallMisses
/ overallAccesses
;
372 for (int i
= 0; i
< system
->maxMasters(); i
++) {
373 overallMissRate
.subname(i
, system
->getMasterName(i
));
376 // miss latency formulas
377 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
378 MemCmd
cmd(access_idx
);
379 const string
&cstr
= cmd
.toString();
381 avgMissLatency
[access_idx
]
382 .name(name() + "." + cstr
+ "_avg_miss_latency")
383 .desc("average " + cstr
+ " miss latency")
384 .flags(total
| nozero
| nonan
)
386 avgMissLatency
[access_idx
] =
387 missLatency
[access_idx
] / misses
[access_idx
];
389 for (int i
= 0; i
< system
->maxMasters(); i
++) {
390 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
395 .name(name() + ".demand_avg_miss_latency")
396 .desc("average overall miss latency")
397 .flags(total
| nozero
| nonan
)
399 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
400 for (int i
= 0; i
< system
->maxMasters(); i
++) {
401 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
404 overallAvgMissLatency
405 .name(name() + ".overall_avg_miss_latency")
406 .desc("average overall miss latency")
407 .flags(total
| nozero
| nonan
)
409 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
410 for (int i
= 0; i
< system
->maxMasters(); i
++) {
411 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
414 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
416 .name(name() + ".blocked_cycles")
417 .desc("number of cycles access was blocked")
418 .subname(Blocked_NoMSHRs
, "no_mshrs")
419 .subname(Blocked_NoTargets
, "no_targets")
423 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
425 .name(name() + ".blocked")
426 .desc("number of cycles access was blocked")
427 .subname(Blocked_NoMSHRs
, "no_mshrs")
428 .subname(Blocked_NoTargets
, "no_targets")
432 .name(name() + ".avg_blocked_cycles")
433 .desc("average number of cycles each access was blocked")
434 .subname(Blocked_NoMSHRs
, "no_mshrs")
435 .subname(Blocked_NoTargets
, "no_targets")
438 avg_blocked
= blocked_cycles
/ blocked_causes
;
441 .name(name() + ".unused_prefetches")
442 .desc("number of HardPF blocks evicted w/o reference")
447 .init(system
->maxMasters())
448 .name(name() + ".writebacks")
449 .desc("number of writebacks")
450 .flags(total
| nozero
| nonan
)
452 for (int i
= 0; i
< system
->maxMasters(); i
++) {
453 writebacks
.subname(i
, system
->getMasterName(i
));
457 // MSHR hit statistics
458 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
459 MemCmd
cmd(access_idx
);
460 const string
&cstr
= cmd
.toString();
462 mshr_hits
[access_idx
]
463 .init(system
->maxMasters())
464 .name(name() + "." + cstr
+ "_mshr_hits")
465 .desc("number of " + cstr
+ " MSHR hits")
466 .flags(total
| nozero
| nonan
)
468 for (int i
= 0; i
< system
->maxMasters(); i
++) {
469 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
474 .name(name() + ".demand_mshr_hits")
475 .desc("number of demand (read+write) MSHR hits")
476 .flags(total
| nozero
| nonan
)
478 demandMshrHits
= SUM_DEMAND(mshr_hits
);
479 for (int i
= 0; i
< system
->maxMasters(); i
++) {
480 demandMshrHits
.subname(i
, system
->getMasterName(i
));
484 .name(name() + ".overall_mshr_hits")
485 .desc("number of overall MSHR hits")
486 .flags(total
| nozero
| nonan
)
488 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
489 for (int i
= 0; i
< system
->maxMasters(); i
++) {
490 overallMshrHits
.subname(i
, system
->getMasterName(i
));
493 // MSHR miss statistics
494 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
495 MemCmd
cmd(access_idx
);
496 const string
&cstr
= cmd
.toString();
498 mshr_misses
[access_idx
]
499 .init(system
->maxMasters())
500 .name(name() + "." + cstr
+ "_mshr_misses")
501 .desc("number of " + cstr
+ " MSHR misses")
502 .flags(total
| nozero
| nonan
)
504 for (int i
= 0; i
< system
->maxMasters(); i
++) {
505 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
510 .name(name() + ".demand_mshr_misses")
511 .desc("number of demand (read+write) MSHR misses")
512 .flags(total
| nozero
| nonan
)
514 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
515 for (int i
= 0; i
< system
->maxMasters(); i
++) {
516 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
520 .name(name() + ".overall_mshr_misses")
521 .desc("number of overall MSHR misses")
522 .flags(total
| nozero
| nonan
)
524 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
525 for (int i
= 0; i
< system
->maxMasters(); i
++) {
526 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
529 // MSHR miss latency statistics
530 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
531 MemCmd
cmd(access_idx
);
532 const string
&cstr
= cmd
.toString();
534 mshr_miss_latency
[access_idx
]
535 .init(system
->maxMasters())
536 .name(name() + "." + cstr
+ "_mshr_miss_latency")
537 .desc("number of " + cstr
+ " MSHR miss cycles")
538 .flags(total
| nozero
| nonan
)
540 for (int i
= 0; i
< system
->maxMasters(); i
++) {
541 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
545 demandMshrMissLatency
546 .name(name() + ".demand_mshr_miss_latency")
547 .desc("number of demand (read+write) MSHR miss cycles")
548 .flags(total
| nozero
| nonan
)
550 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
551 for (int i
= 0; i
< system
->maxMasters(); i
++) {
552 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
555 overallMshrMissLatency
556 .name(name() + ".overall_mshr_miss_latency")
557 .desc("number of overall MSHR miss cycles")
558 .flags(total
| nozero
| nonan
)
560 overallMshrMissLatency
=
561 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
562 for (int i
= 0; i
< system
->maxMasters(); i
++) {
563 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
566 // MSHR uncacheable statistics
567 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
568 MemCmd
cmd(access_idx
);
569 const string
&cstr
= cmd
.toString();
571 mshr_uncacheable
[access_idx
]
572 .init(system
->maxMasters())
573 .name(name() + "." + cstr
+ "_mshr_uncacheable")
574 .desc("number of " + cstr
+ " MSHR uncacheable")
575 .flags(total
| nozero
| nonan
)
577 for (int i
= 0; i
< system
->maxMasters(); i
++) {
578 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
582 overallMshrUncacheable
583 .name(name() + ".overall_mshr_uncacheable_misses")
584 .desc("number of overall MSHR uncacheable misses")
585 .flags(total
| nozero
| nonan
)
587 overallMshrUncacheable
=
588 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
589 for (int i
= 0; i
< system
->maxMasters(); i
++) {
590 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
593 // MSHR miss latency statistics
594 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
595 MemCmd
cmd(access_idx
);
596 const string
&cstr
= cmd
.toString();
598 mshr_uncacheable_lat
[access_idx
]
599 .init(system
->maxMasters())
600 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
601 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
602 .flags(total
| nozero
| nonan
)
604 for (int i
= 0; i
< system
->maxMasters(); i
++) {
605 mshr_uncacheable_lat
[access_idx
].subname(
606 i
, system
->getMasterName(i
));
610 overallMshrUncacheableLatency
611 .name(name() + ".overall_mshr_uncacheable_latency")
612 .desc("number of overall MSHR uncacheable cycles")
613 .flags(total
| nozero
| nonan
)
615 overallMshrUncacheableLatency
=
616 SUM_DEMAND(mshr_uncacheable_lat
) +
617 SUM_NON_DEMAND(mshr_uncacheable_lat
);
618 for (int i
= 0; i
< system
->maxMasters(); i
++) {
619 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
623 // MSHR access formulas
624 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
625 MemCmd
cmd(access_idx
);
626 const string
&cstr
= cmd
.toString();
628 mshrAccesses
[access_idx
]
629 .name(name() + "." + cstr
+ "_mshr_accesses")
630 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
631 .flags(total
| nozero
| nonan
)
633 mshrAccesses
[access_idx
] =
634 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
635 + mshr_uncacheable
[access_idx
];
639 .name(name() + ".demand_mshr_accesses")
640 .desc("number of demand (read+write) mshr accesses")
641 .flags(total
| nozero
| nonan
)
643 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
646 .name(name() + ".overall_mshr_accesses")
647 .desc("number of overall (read+write) mshr accesses")
648 .flags(total
| nozero
| nonan
)
650 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
651 + overallMshrUncacheable
;
654 // MSHR miss rate formulas
655 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
656 MemCmd
cmd(access_idx
);
657 const string
&cstr
= cmd
.toString();
659 mshrMissRate
[access_idx
]
660 .name(name() + "." + cstr
+ "_mshr_miss_rate")
661 .desc("mshr miss rate for " + cstr
+ " accesses")
662 .flags(total
| nozero
| nonan
)
664 mshrMissRate
[access_idx
] =
665 mshr_misses
[access_idx
] / accesses
[access_idx
];
667 for (int i
= 0; i
< system
->maxMasters(); i
++) {
668 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
673 .name(name() + ".demand_mshr_miss_rate")
674 .desc("mshr miss rate for demand accesses")
675 .flags(total
| nozero
| nonan
)
677 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
678 for (int i
= 0; i
< system
->maxMasters(); i
++) {
679 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
683 .name(name() + ".overall_mshr_miss_rate")
684 .desc("mshr miss rate for overall accesses")
685 .flags(total
| nozero
| nonan
)
687 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
688 for (int i
= 0; i
< system
->maxMasters(); i
++) {
689 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
692 // mshrMiss latency formulas
693 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
694 MemCmd
cmd(access_idx
);
695 const string
&cstr
= cmd
.toString();
697 avgMshrMissLatency
[access_idx
]
698 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
699 .desc("average " + cstr
+ " mshr miss latency")
700 .flags(total
| nozero
| nonan
)
702 avgMshrMissLatency
[access_idx
] =
703 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
705 for (int i
= 0; i
< system
->maxMasters(); i
++) {
706 avgMshrMissLatency
[access_idx
].subname(
707 i
, system
->getMasterName(i
));
711 demandAvgMshrMissLatency
712 .name(name() + ".demand_avg_mshr_miss_latency")
713 .desc("average overall mshr miss latency")
714 .flags(total
| nozero
| nonan
)
716 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
717 for (int i
= 0; i
< system
->maxMasters(); i
++) {
718 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
721 overallAvgMshrMissLatency
722 .name(name() + ".overall_avg_mshr_miss_latency")
723 .desc("average overall mshr miss latency")
724 .flags(total
| nozero
| nonan
)
726 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
727 for (int i
= 0; i
< system
->maxMasters(); i
++) {
728 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
731 // mshrUncacheable latency formulas
732 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
733 MemCmd
cmd(access_idx
);
734 const string
&cstr
= cmd
.toString();
736 avgMshrUncacheableLatency
[access_idx
]
737 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
738 .desc("average " + cstr
+ " mshr uncacheable latency")
739 .flags(total
| nozero
| nonan
)
741 avgMshrUncacheableLatency
[access_idx
] =
742 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
744 for (int i
= 0; i
< system
->maxMasters(); i
++) {
745 avgMshrUncacheableLatency
[access_idx
].subname(
746 i
, system
->getMasterName(i
));
750 overallAvgMshrUncacheableLatency
751 .name(name() + ".overall_avg_mshr_uncacheable_latency")
752 .desc("average overall mshr uncacheable latency")
753 .flags(total
| nozero
| nonan
)
755 overallAvgMshrUncacheableLatency
=
756 overallMshrUncacheableLatency
/ overallMshrUncacheable
;
757 for (int i
= 0; i
< system
->maxMasters(); i
++) {
758 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));