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