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 "debug/Cache.hh"
49 #include "debug/Drain.hh"
50 #include "mem/cache/tags/fa_lru.hh"
51 #include "mem/cache/tags/lru.hh"
52 #include "mem/cache/tags/random_repl.hh"
53 #include "mem/cache/base.hh"
54 #include "mem/cache/cache.hh"
55 #include "mem/cache/mshr.hh"
56 #include "sim/full_system.hh"
60 BaseCache::CacheSlavePort::CacheSlavePort(const std::string
&_name
,
62 const std::string
&_label
)
63 : QueuedSlavePort(_name
, _cache
, queue
), queue(*_cache
, *this, _label
),
64 blocked(false), mustSendRetry(false), sendRetryEvent(this)
68 BaseCache::BaseCache(const Params
*p
)
70 cpuSidePort(nullptr), memSidePort(nullptr),
71 mshrQueue("MSHRs", p
->mshrs
, 4, p
->demand_mshr_reserve
, MSHRQueue_MSHRs
),
72 writeBuffer("write buffer", p
->write_buffers
, p
->mshrs
+1000, 0,
73 MSHRQueue_WriteBuffer
),
74 blkSize(p
->system
->cacheLineSize()),
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
),
80 forwardSnoops(p
->forward_snoops
),
81 isTopLevel(p
->is_top_level
),
82 isReadOnly(p
->is_read_only
),
86 missCount(p
->max_miss_count
),
87 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
93 BaseCache::CacheSlavePort::setBlocked()
96 DPRINTF(CachePort
, "Port is blocking new requests\n");
98 // if we already scheduled a retry in this cycle, but it has not yet
99 // happened, cancel it
100 if (sendRetryEvent
.scheduled()) {
101 owner
.deschedule(sendRetryEvent
);
102 DPRINTF(CachePort
, "Port descheduled retry\n");
103 mustSendRetry
= true;
108 BaseCache::CacheSlavePort::clearBlocked()
111 DPRINTF(CachePort
, "Port is accepting new requests\n");
114 // @TODO: need to find a better time (next cycle?)
115 owner
.schedule(sendRetryEvent
, curTick() + 1);
120 BaseCache::CacheSlavePort::processSendRetry()
122 DPRINTF(CachePort
, "Port is sending retry\n");
124 // reset the flag and call retry
125 mustSendRetry
= false;
132 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
133 fatal("Cache ports on %s are not connected\n", name());
134 cpuSidePort
->sendRangeChange();
138 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
140 if (if_name
== "mem_side") {
143 return MemObject::getMasterPort(if_name
, idx
);
148 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
150 if (if_name
== "cpu_side") {
153 return MemObject::getSlavePort(if_name
, idx
);
158 BaseCache::inRange(Addr addr
) const
160 for (const auto& r
: addrRanges
) {
161 if (r
.contains(addr
)) {
169 BaseCache::regStats()
171 using namespace Stats
;
174 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
175 MemCmd
cmd(access_idx
);
176 const string
&cstr
= cmd
.toString();
179 .init(system
->maxMasters())
180 .name(name() + "." + cstr
+ "_hits")
181 .desc("number of " + cstr
+ " hits")
182 .flags(total
| nozero
| nonan
)
184 for (int i
= 0; i
< system
->maxMasters(); i
++) {
185 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
189 // These macros make it easier to sum the right subset of commands and
190 // to change the subset of commands that are considered "demand" vs
192 #define SUM_DEMAND(s) \
193 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
195 // should writebacks be included here? prior code was inconsistent...
196 #define SUM_NON_DEMAND(s) \
197 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
200 .name(name() + ".demand_hits")
201 .desc("number of demand (read+write) hits")
202 .flags(total
| nozero
| nonan
)
204 demandHits
= SUM_DEMAND(hits
);
205 for (int i
= 0; i
< system
->maxMasters(); i
++) {
206 demandHits
.subname(i
, system
->getMasterName(i
));
210 .name(name() + ".overall_hits")
211 .desc("number of overall hits")
212 .flags(total
| nozero
| nonan
)
214 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
215 for (int i
= 0; i
< system
->maxMasters(); i
++) {
216 overallHits
.subname(i
, system
->getMasterName(i
));
220 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
221 MemCmd
cmd(access_idx
);
222 const string
&cstr
= cmd
.toString();
225 .init(system
->maxMasters())
226 .name(name() + "." + cstr
+ "_misses")
227 .desc("number of " + cstr
+ " misses")
228 .flags(total
| nozero
| nonan
)
230 for (int i
= 0; i
< system
->maxMasters(); i
++) {
231 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
236 .name(name() + ".demand_misses")
237 .desc("number of demand (read+write) misses")
238 .flags(total
| nozero
| nonan
)
240 demandMisses
= SUM_DEMAND(misses
);
241 for (int i
= 0; i
< system
->maxMasters(); i
++) {
242 demandMisses
.subname(i
, system
->getMasterName(i
));
246 .name(name() + ".overall_misses")
247 .desc("number of overall misses")
248 .flags(total
| nozero
| nonan
)
250 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
251 for (int i
= 0; i
< system
->maxMasters(); i
++) {
252 overallMisses
.subname(i
, system
->getMasterName(i
));
255 // Miss latency statistics
256 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
257 MemCmd
cmd(access_idx
);
258 const string
&cstr
= cmd
.toString();
260 missLatency
[access_idx
]
261 .init(system
->maxMasters())
262 .name(name() + "." + cstr
+ "_miss_latency")
263 .desc("number of " + cstr
+ " miss cycles")
264 .flags(total
| nozero
| nonan
)
266 for (int i
= 0; i
< system
->maxMasters(); i
++) {
267 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
272 .name(name() + ".demand_miss_latency")
273 .desc("number of demand (read+write) miss cycles")
274 .flags(total
| nozero
| nonan
)
276 demandMissLatency
= SUM_DEMAND(missLatency
);
277 for (int i
= 0; i
< system
->maxMasters(); i
++) {
278 demandMissLatency
.subname(i
, system
->getMasterName(i
));
282 .name(name() + ".overall_miss_latency")
283 .desc("number of overall miss cycles")
284 .flags(total
| nozero
| nonan
)
286 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
287 for (int i
= 0; i
< system
->maxMasters(); i
++) {
288 overallMissLatency
.subname(i
, system
->getMasterName(i
));
292 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
293 MemCmd
cmd(access_idx
);
294 const string
&cstr
= cmd
.toString();
297 .name(name() + "." + cstr
+ "_accesses")
298 .desc("number of " + cstr
+ " accesses(hits+misses)")
299 .flags(total
| nozero
| nonan
)
301 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
303 for (int i
= 0; i
< system
->maxMasters(); i
++) {
304 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
309 .name(name() + ".demand_accesses")
310 .desc("number of demand (read+write) accesses")
311 .flags(total
| nozero
| nonan
)
313 demandAccesses
= demandHits
+ demandMisses
;
314 for (int i
= 0; i
< system
->maxMasters(); i
++) {
315 demandAccesses
.subname(i
, system
->getMasterName(i
));
319 .name(name() + ".overall_accesses")
320 .desc("number of overall (read+write) accesses")
321 .flags(total
| nozero
| nonan
)
323 overallAccesses
= overallHits
+ overallMisses
;
324 for (int i
= 0; i
< system
->maxMasters(); i
++) {
325 overallAccesses
.subname(i
, system
->getMasterName(i
));
328 // miss rate formulas
329 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
330 MemCmd
cmd(access_idx
);
331 const string
&cstr
= cmd
.toString();
334 .name(name() + "." + cstr
+ "_miss_rate")
335 .desc("miss rate for " + cstr
+ " accesses")
336 .flags(total
| nozero
| nonan
)
338 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
340 for (int i
= 0; i
< system
->maxMasters(); i
++) {
341 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
346 .name(name() + ".demand_miss_rate")
347 .desc("miss rate for demand accesses")
348 .flags(total
| nozero
| nonan
)
350 demandMissRate
= demandMisses
/ demandAccesses
;
351 for (int i
= 0; i
< system
->maxMasters(); i
++) {
352 demandMissRate
.subname(i
, system
->getMasterName(i
));
356 .name(name() + ".overall_miss_rate")
357 .desc("miss rate for overall accesses")
358 .flags(total
| nozero
| nonan
)
360 overallMissRate
= overallMisses
/ overallAccesses
;
361 for (int i
= 0; i
< system
->maxMasters(); i
++) {
362 overallMissRate
.subname(i
, system
->getMasterName(i
));
365 // miss latency formulas
366 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
367 MemCmd
cmd(access_idx
);
368 const string
&cstr
= cmd
.toString();
370 avgMissLatency
[access_idx
]
371 .name(name() + "." + cstr
+ "_avg_miss_latency")
372 .desc("average " + cstr
+ " miss latency")
373 .flags(total
| nozero
| nonan
)
375 avgMissLatency
[access_idx
] =
376 missLatency
[access_idx
] / misses
[access_idx
];
378 for (int i
= 0; i
< system
->maxMasters(); i
++) {
379 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
384 .name(name() + ".demand_avg_miss_latency")
385 .desc("average overall miss latency")
386 .flags(total
| nozero
| nonan
)
388 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
389 for (int i
= 0; i
< system
->maxMasters(); i
++) {
390 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
393 overallAvgMissLatency
394 .name(name() + ".overall_avg_miss_latency")
395 .desc("average overall miss latency")
396 .flags(total
| nozero
| nonan
)
398 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
399 for (int i
= 0; i
< system
->maxMasters(); i
++) {
400 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
403 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
405 .name(name() + ".blocked_cycles")
406 .desc("number of cycles access was blocked")
407 .subname(Blocked_NoMSHRs
, "no_mshrs")
408 .subname(Blocked_NoTargets
, "no_targets")
412 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
414 .name(name() + ".blocked")
415 .desc("number of cycles access was blocked")
416 .subname(Blocked_NoMSHRs
, "no_mshrs")
417 .subname(Blocked_NoTargets
, "no_targets")
421 .name(name() + ".avg_blocked_cycles")
422 .desc("average number of cycles each access was blocked")
423 .subname(Blocked_NoMSHRs
, "no_mshrs")
424 .subname(Blocked_NoTargets
, "no_targets")
427 avg_blocked
= blocked_cycles
/ blocked_causes
;
430 .name(name() + ".fast_writes")
431 .desc("number of fast writes performed")
435 .name(name() + ".cache_copies")
436 .desc("number of cache copies performed")
440 .init(system
->maxMasters())
441 .name(name() + ".writebacks")
442 .desc("number of writebacks")
443 .flags(total
| nozero
| nonan
)
445 for (int i
= 0; i
< system
->maxMasters(); i
++) {
446 writebacks
.subname(i
, system
->getMasterName(i
));
450 // MSHR hit statistics
451 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
452 MemCmd
cmd(access_idx
);
453 const string
&cstr
= cmd
.toString();
455 mshr_hits
[access_idx
]
456 .init(system
->maxMasters())
457 .name(name() + "." + cstr
+ "_mshr_hits")
458 .desc("number of " + cstr
+ " MSHR hits")
459 .flags(total
| nozero
| nonan
)
461 for (int i
= 0; i
< system
->maxMasters(); i
++) {
462 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
467 .name(name() + ".demand_mshr_hits")
468 .desc("number of demand (read+write) MSHR hits")
469 .flags(total
| nozero
| nonan
)
471 demandMshrHits
= SUM_DEMAND(mshr_hits
);
472 for (int i
= 0; i
< system
->maxMasters(); i
++) {
473 demandMshrHits
.subname(i
, system
->getMasterName(i
));
477 .name(name() + ".overall_mshr_hits")
478 .desc("number of overall MSHR hits")
479 .flags(total
| nozero
| nonan
)
481 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
482 for (int i
= 0; i
< system
->maxMasters(); i
++) {
483 overallMshrHits
.subname(i
, system
->getMasterName(i
));
486 // MSHR miss statistics
487 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
488 MemCmd
cmd(access_idx
);
489 const string
&cstr
= cmd
.toString();
491 mshr_misses
[access_idx
]
492 .init(system
->maxMasters())
493 .name(name() + "." + cstr
+ "_mshr_misses")
494 .desc("number of " + cstr
+ " MSHR misses")
495 .flags(total
| nozero
| nonan
)
497 for (int i
= 0; i
< system
->maxMasters(); i
++) {
498 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
503 .name(name() + ".demand_mshr_misses")
504 .desc("number of demand (read+write) MSHR misses")
505 .flags(total
| nozero
| nonan
)
507 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
508 for (int i
= 0; i
< system
->maxMasters(); i
++) {
509 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
513 .name(name() + ".overall_mshr_misses")
514 .desc("number of overall MSHR misses")
515 .flags(total
| nozero
| nonan
)
517 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
518 for (int i
= 0; i
< system
->maxMasters(); i
++) {
519 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
522 // MSHR miss latency statistics
523 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
524 MemCmd
cmd(access_idx
);
525 const string
&cstr
= cmd
.toString();
527 mshr_miss_latency
[access_idx
]
528 .init(system
->maxMasters())
529 .name(name() + "." + cstr
+ "_mshr_miss_latency")
530 .desc("number of " + cstr
+ " MSHR miss cycles")
531 .flags(total
| nozero
| nonan
)
533 for (int i
= 0; i
< system
->maxMasters(); i
++) {
534 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
538 demandMshrMissLatency
539 .name(name() + ".demand_mshr_miss_latency")
540 .desc("number of demand (read+write) MSHR miss cycles")
541 .flags(total
| nozero
| nonan
)
543 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
544 for (int i
= 0; i
< system
->maxMasters(); i
++) {
545 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
548 overallMshrMissLatency
549 .name(name() + ".overall_mshr_miss_latency")
550 .desc("number of overall MSHR miss cycles")
551 .flags(total
| nozero
| nonan
)
553 overallMshrMissLatency
=
554 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
555 for (int i
= 0; i
< system
->maxMasters(); i
++) {
556 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
559 // MSHR uncacheable statistics
560 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
561 MemCmd
cmd(access_idx
);
562 const string
&cstr
= cmd
.toString();
564 mshr_uncacheable
[access_idx
]
565 .init(system
->maxMasters())
566 .name(name() + "." + cstr
+ "_mshr_uncacheable")
567 .desc("number of " + cstr
+ " MSHR uncacheable")
568 .flags(total
| nozero
| nonan
)
570 for (int i
= 0; i
< system
->maxMasters(); i
++) {
571 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
575 overallMshrUncacheable
576 .name(name() + ".overall_mshr_uncacheable_misses")
577 .desc("number of overall MSHR uncacheable misses")
578 .flags(total
| nozero
| nonan
)
580 overallMshrUncacheable
=
581 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
582 for (int i
= 0; i
< system
->maxMasters(); i
++) {
583 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
586 // MSHR miss latency statistics
587 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
588 MemCmd
cmd(access_idx
);
589 const string
&cstr
= cmd
.toString();
591 mshr_uncacheable_lat
[access_idx
]
592 .init(system
->maxMasters())
593 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
594 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
595 .flags(total
| nozero
| nonan
)
597 for (int i
= 0; i
< system
->maxMasters(); i
++) {
598 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
602 overallMshrUncacheableLatency
603 .name(name() + ".overall_mshr_uncacheable_latency")
604 .desc("number of overall MSHR uncacheable cycles")
605 .flags(total
| nozero
| nonan
)
607 overallMshrUncacheableLatency
=
608 SUM_DEMAND(mshr_uncacheable_lat
) +
609 SUM_NON_DEMAND(mshr_uncacheable_lat
);
610 for (int i
= 0; i
< system
->maxMasters(); i
++) {
611 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
615 // MSHR access formulas
616 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
617 MemCmd
cmd(access_idx
);
618 const string
&cstr
= cmd
.toString();
620 mshrAccesses
[access_idx
]
621 .name(name() + "." + cstr
+ "_mshr_accesses")
622 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
623 .flags(total
| nozero
| nonan
)
625 mshrAccesses
[access_idx
] =
626 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
627 + mshr_uncacheable
[access_idx
];
631 .name(name() + ".demand_mshr_accesses")
632 .desc("number of demand (read+write) mshr accesses")
633 .flags(total
| nozero
| nonan
)
635 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
638 .name(name() + ".overall_mshr_accesses")
639 .desc("number of overall (read+write) mshr accesses")
640 .flags(total
| nozero
| nonan
)
642 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
643 + overallMshrUncacheable
;
646 // MSHR miss rate formulas
647 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
648 MemCmd
cmd(access_idx
);
649 const string
&cstr
= cmd
.toString();
651 mshrMissRate
[access_idx
]
652 .name(name() + "." + cstr
+ "_mshr_miss_rate")
653 .desc("mshr miss rate for " + cstr
+ " accesses")
654 .flags(total
| nozero
| nonan
)
656 mshrMissRate
[access_idx
] =
657 mshr_misses
[access_idx
] / accesses
[access_idx
];
659 for (int i
= 0; i
< system
->maxMasters(); i
++) {
660 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
665 .name(name() + ".demand_mshr_miss_rate")
666 .desc("mshr miss rate for demand accesses")
667 .flags(total
| nozero
| nonan
)
669 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
670 for (int i
= 0; i
< system
->maxMasters(); i
++) {
671 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
675 .name(name() + ".overall_mshr_miss_rate")
676 .desc("mshr miss rate for overall accesses")
677 .flags(total
| nozero
| nonan
)
679 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
680 for (int i
= 0; i
< system
->maxMasters(); i
++) {
681 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
684 // mshrMiss latency formulas
685 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
686 MemCmd
cmd(access_idx
);
687 const string
&cstr
= cmd
.toString();
689 avgMshrMissLatency
[access_idx
]
690 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
691 .desc("average " + cstr
+ " mshr miss latency")
692 .flags(total
| nozero
| nonan
)
694 avgMshrMissLatency
[access_idx
] =
695 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
697 for (int i
= 0; i
< system
->maxMasters(); i
++) {
698 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
702 demandAvgMshrMissLatency
703 .name(name() + ".demand_avg_mshr_miss_latency")
704 .desc("average overall mshr miss latency")
705 .flags(total
| nozero
| nonan
)
707 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
708 for (int i
= 0; i
< system
->maxMasters(); i
++) {
709 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
712 overallAvgMshrMissLatency
713 .name(name() + ".overall_avg_mshr_miss_latency")
714 .desc("average overall mshr miss latency")
715 .flags(total
| nozero
| nonan
)
717 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
718 for (int i
= 0; i
< system
->maxMasters(); i
++) {
719 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
722 // mshrUncacheable latency formulas
723 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
724 MemCmd
cmd(access_idx
);
725 const string
&cstr
= cmd
.toString();
727 avgMshrUncacheableLatency
[access_idx
]
728 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
729 .desc("average " + cstr
+ " mshr uncacheable latency")
730 .flags(total
| nozero
| nonan
)
732 avgMshrUncacheableLatency
[access_idx
] =
733 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
735 for (int i
= 0; i
< system
->maxMasters(); i
++) {
736 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
740 overallAvgMshrUncacheableLatency
741 .name(name() + ".overall_avg_mshr_uncacheable_latency")
742 .desc("average overall mshr uncacheable latency")
743 .flags(total
| nozero
| nonan
)
745 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
746 for (int i
= 0; i
< system
->maxMasters(); i
++) {
747 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
751 .init(system
->maxMasters())
752 .name(name() + ".mshr_cap_events")
753 .desc("number of times MSHR cap was activated")
754 .flags(total
| nozero
| nonan
)
756 for (int i
= 0; i
< system
->maxMasters(); i
++) {
757 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
760 //software prefetching stats
761 soft_prefetch_mshr_full
762 .init(system
->maxMasters())
763 .name(name() + ".soft_prefetch_mshr_full")
764 .desc("number of mshr full events for SW prefetching instrutions")
765 .flags(total
| nozero
| nonan
)
767 for (int i
= 0; i
< system
->maxMasters(); i
++) {
768 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
771 mshr_no_allocate_misses
772 .name(name() +".no_allocate_misses")
773 .desc("Number of misses that were no-allocate")
779 BaseCache::drain(DrainManager
*dm
)
781 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
782 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
786 setDrainState(Drainable::Draining
);
787 DPRINTF(Drain
, "Cache not drained\n");
791 setDrainState(Drainable::Drained
);
796 BaseCacheParams::create()
800 return new Cache(this);