Deleted Added
sdiff udiff text old ( 12084:5a3769ff3d55 ) new ( 12600:e670dd17c8cf )
full compact
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}