2 * Copyright (c) 2012 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 "cpu/base.hh"
50 #include "debug/Cache.hh"
51 #include "mem/cache/base.hh"
52 #include "mem/cache/mshr.hh"
53 #include "sim/full_system.hh"
57 BaseCache::CacheMasterPort::CacheMasterPort(const std::string
&_name
,
59 const std::string
&_label
)
60 : SimpleTimingPort(_name
, _cache
, _label
)
64 BaseCache::CacheSlavePort::CacheSlavePort(const std::string
&_name
,
66 const std::string
&_label
)
67 : SimpleTimingPort(_name
, _cache
, _label
), blocked(false),
68 mustSendRetry(false), sendRetryEvent(this)
72 BaseCache::BaseCache(const Params
*p
)
74 mshrQueue("MSHRs", p
->mshrs
, 4, MSHRQueue_MSHRs
),
75 writeBuffer("write buffer", p
->write_buffers
, p
->mshrs
+1000,
76 MSHRQueue_WriteBuffer
),
77 blkSize(p
->block_size
),
78 hitLatency(p
->latency
),
79 numTarget(p
->tgts_per_mshr
),
80 forwardSnoops(p
->forward_snoops
),
81 isTopLevel(p
->is_top_level
),
84 missCount(p
->max_miss_count
),
86 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
92 BaseCache::CacheSlavePort::setBlocked()
95 DPRINTF(CachePort
, "Cache port %s blocking new requests\n", name());
100 BaseCache::CacheSlavePort::clearBlocked()
103 DPRINTF(CachePort
, "Cache port %s accepting new requests\n", name());
106 DPRINTF(CachePort
, "Cache port %s sending retry\n", name());
107 mustSendRetry
= false;
108 // @TODO: need to find a better time (next bus cycle?)
109 owner
->schedule(sendRetryEvent
, curTick() + 1);
117 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
118 panic("Cache %s not hooked up on both sides\n", name());
119 cpuSidePort
->sendRangeChange();
124 BaseCache::regStats()
126 using namespace Stats
;
129 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
130 MemCmd
cmd(access_idx
);
131 const string
&cstr
= cmd
.toString();
134 .init(system
->maxMasters())
135 .name(name() + "." + cstr
+ "_hits")
136 .desc("number of " + cstr
+ " hits")
137 .flags(total
| nozero
| nonan
)
139 for (int i
= 0; i
< system
->maxMasters(); i
++) {
140 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
144 // These macros make it easier to sum the right subset of commands and
145 // to change the subset of commands that are considered "demand" vs
147 #define SUM_DEMAND(s) \
148 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
150 // should writebacks be included here? prior code was inconsistent...
151 #define SUM_NON_DEMAND(s) \
152 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
155 .name(name() + ".demand_hits")
156 .desc("number of demand (read+write) hits")
157 .flags(total
| nozero
| nonan
)
159 demandHits
= SUM_DEMAND(hits
);
160 for (int i
= 0; i
< system
->maxMasters(); i
++) {
161 demandHits
.subname(i
, system
->getMasterName(i
));
165 .name(name() + ".overall_hits")
166 .desc("number of overall hits")
167 .flags(total
| nozero
| nonan
)
169 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
170 for (int i
= 0; i
< system
->maxMasters(); i
++) {
171 overallHits
.subname(i
, system
->getMasterName(i
));
175 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
176 MemCmd
cmd(access_idx
);
177 const string
&cstr
= cmd
.toString();
180 .init(system
->maxMasters())
181 .name(name() + "." + cstr
+ "_misses")
182 .desc("number of " + cstr
+ " misses")
183 .flags(total
| nozero
| nonan
)
185 for (int i
= 0; i
< system
->maxMasters(); i
++) {
186 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
191 .name(name() + ".demand_misses")
192 .desc("number of demand (read+write) misses")
193 .flags(total
| nozero
| nonan
)
195 demandMisses
= SUM_DEMAND(misses
);
196 for (int i
= 0; i
< system
->maxMasters(); i
++) {
197 demandMisses
.subname(i
, system
->getMasterName(i
));
201 .name(name() + ".overall_misses")
202 .desc("number of overall misses")
203 .flags(total
| nozero
| nonan
)
205 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
206 for (int i
= 0; i
< system
->maxMasters(); i
++) {
207 overallMisses
.subname(i
, system
->getMasterName(i
));
210 // Miss latency statistics
211 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
212 MemCmd
cmd(access_idx
);
213 const string
&cstr
= cmd
.toString();
215 missLatency
[access_idx
]
216 .init(system
->maxMasters())
217 .name(name() + "." + cstr
+ "_miss_latency")
218 .desc("number of " + cstr
+ " miss cycles")
219 .flags(total
| nozero
| nonan
)
221 for (int i
= 0; i
< system
->maxMasters(); i
++) {
222 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
227 .name(name() + ".demand_miss_latency")
228 .desc("number of demand (read+write) miss cycles")
229 .flags(total
| nozero
| nonan
)
231 demandMissLatency
= SUM_DEMAND(missLatency
);
232 for (int i
= 0; i
< system
->maxMasters(); i
++) {
233 demandMissLatency
.subname(i
, system
->getMasterName(i
));
237 .name(name() + ".overall_miss_latency")
238 .desc("number of overall miss cycles")
239 .flags(total
| nozero
| nonan
)
241 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
242 for (int i
= 0; i
< system
->maxMasters(); i
++) {
243 overallMissLatency
.subname(i
, system
->getMasterName(i
));
247 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
248 MemCmd
cmd(access_idx
);
249 const string
&cstr
= cmd
.toString();
252 .name(name() + "." + cstr
+ "_accesses")
253 .desc("number of " + cstr
+ " accesses(hits+misses)")
254 .flags(total
| nozero
| nonan
)
256 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
258 for (int i
= 0; i
< system
->maxMasters(); i
++) {
259 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
264 .name(name() + ".demand_accesses")
265 .desc("number of demand (read+write) accesses")
266 .flags(total
| nozero
| nonan
)
268 demandAccesses
= demandHits
+ demandMisses
;
269 for (int i
= 0; i
< system
->maxMasters(); i
++) {
270 demandAccesses
.subname(i
, system
->getMasterName(i
));
274 .name(name() + ".overall_accesses")
275 .desc("number of overall (read+write) accesses")
276 .flags(total
| nozero
| nonan
)
278 overallAccesses
= overallHits
+ overallMisses
;
279 for (int i
= 0; i
< system
->maxMasters(); i
++) {
280 overallAccesses
.subname(i
, system
->getMasterName(i
));
283 // miss rate formulas
284 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
285 MemCmd
cmd(access_idx
);
286 const string
&cstr
= cmd
.toString();
289 .name(name() + "." + cstr
+ "_miss_rate")
290 .desc("miss rate for " + cstr
+ " accesses")
291 .flags(total
| nozero
| nonan
)
293 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
295 for (int i
= 0; i
< system
->maxMasters(); i
++) {
296 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
301 .name(name() + ".demand_miss_rate")
302 .desc("miss rate for demand accesses")
303 .flags(total
| nozero
| nonan
)
305 demandMissRate
= demandMisses
/ demandAccesses
;
306 for (int i
= 0; i
< system
->maxMasters(); i
++) {
307 demandMissRate
.subname(i
, system
->getMasterName(i
));
311 .name(name() + ".overall_miss_rate")
312 .desc("miss rate for overall accesses")
313 .flags(total
| nozero
| nonan
)
315 overallMissRate
= overallMisses
/ overallAccesses
;
316 for (int i
= 0; i
< system
->maxMasters(); i
++) {
317 overallMissRate
.subname(i
, system
->getMasterName(i
));
320 // miss latency formulas
321 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
322 MemCmd
cmd(access_idx
);
323 const string
&cstr
= cmd
.toString();
325 avgMissLatency
[access_idx
]
326 .name(name() + "." + cstr
+ "_avg_miss_latency")
327 .desc("average " + cstr
+ " miss latency")
328 .flags(total
| nozero
| nonan
)
330 avgMissLatency
[access_idx
] =
331 missLatency
[access_idx
] / misses
[access_idx
];
333 for (int i
= 0; i
< system
->maxMasters(); i
++) {
334 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
339 .name(name() + ".demand_avg_miss_latency")
340 .desc("average overall miss latency")
341 .flags(total
| nozero
| nonan
)
343 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
344 for (int i
= 0; i
< system
->maxMasters(); i
++) {
345 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
348 overallAvgMissLatency
349 .name(name() + ".overall_avg_miss_latency")
350 .desc("average overall miss latency")
351 .flags(total
| nozero
| nonan
)
353 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
354 for (int i
= 0; i
< system
->maxMasters(); i
++) {
355 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
358 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
360 .name(name() + ".blocked_cycles")
361 .desc("number of cycles access was blocked")
362 .subname(Blocked_NoMSHRs
, "no_mshrs")
363 .subname(Blocked_NoTargets
, "no_targets")
367 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
369 .name(name() + ".blocked")
370 .desc("number of cycles access was blocked")
371 .subname(Blocked_NoMSHRs
, "no_mshrs")
372 .subname(Blocked_NoTargets
, "no_targets")
376 .name(name() + ".avg_blocked_cycles")
377 .desc("average number of cycles each access was blocked")
378 .subname(Blocked_NoMSHRs
, "no_mshrs")
379 .subname(Blocked_NoTargets
, "no_targets")
382 avg_blocked
= blocked_cycles
/ blocked_causes
;
385 .name(name() + ".fast_writes")
386 .desc("number of fast writes performed")
390 .name(name() + ".cache_copies")
391 .desc("number of cache copies performed")
395 .init(system
->maxMasters())
396 .name(name() + ".writebacks")
397 .desc("number of writebacks")
398 .flags(total
| nozero
| nonan
)
400 for (int i
= 0; i
< system
->maxMasters(); i
++) {
401 writebacks
.subname(i
, system
->getMasterName(i
));
405 // MSHR hit statistics
406 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
407 MemCmd
cmd(access_idx
);
408 const string
&cstr
= cmd
.toString();
410 mshr_hits
[access_idx
]
411 .init(system
->maxMasters())
412 .name(name() + "." + cstr
+ "_mshr_hits")
413 .desc("number of " + cstr
+ " MSHR hits")
414 .flags(total
| nozero
| nonan
)
416 for (int i
= 0; i
< system
->maxMasters(); i
++) {
417 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
422 .name(name() + ".demand_mshr_hits")
423 .desc("number of demand (read+write) MSHR hits")
424 .flags(total
| nozero
| nonan
)
426 demandMshrHits
= SUM_DEMAND(mshr_hits
);
427 for (int i
= 0; i
< system
->maxMasters(); i
++) {
428 demandMshrHits
.subname(i
, system
->getMasterName(i
));
432 .name(name() + ".overall_mshr_hits")
433 .desc("number of overall MSHR hits")
434 .flags(total
| nozero
| nonan
)
436 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
437 for (int i
= 0; i
< system
->maxMasters(); i
++) {
438 overallMshrHits
.subname(i
, system
->getMasterName(i
));
441 // MSHR miss statistics
442 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
443 MemCmd
cmd(access_idx
);
444 const string
&cstr
= cmd
.toString();
446 mshr_misses
[access_idx
]
447 .init(system
->maxMasters())
448 .name(name() + "." + cstr
+ "_mshr_misses")
449 .desc("number of " + cstr
+ " MSHR misses")
450 .flags(total
| nozero
| nonan
)
452 for (int i
= 0; i
< system
->maxMasters(); i
++) {
453 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
458 .name(name() + ".demand_mshr_misses")
459 .desc("number of demand (read+write) MSHR misses")
460 .flags(total
| nozero
| nonan
)
462 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
463 for (int i
= 0; i
< system
->maxMasters(); i
++) {
464 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
468 .name(name() + ".overall_mshr_misses")
469 .desc("number of overall MSHR misses")
470 .flags(total
| nozero
| nonan
)
472 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
473 for (int i
= 0; i
< system
->maxMasters(); i
++) {
474 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
477 // MSHR miss latency statistics
478 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
479 MemCmd
cmd(access_idx
);
480 const string
&cstr
= cmd
.toString();
482 mshr_miss_latency
[access_idx
]
483 .init(system
->maxMasters())
484 .name(name() + "." + cstr
+ "_mshr_miss_latency")
485 .desc("number of " + cstr
+ " MSHR miss cycles")
486 .flags(total
| nozero
| nonan
)
488 for (int i
= 0; i
< system
->maxMasters(); i
++) {
489 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
493 demandMshrMissLatency
494 .name(name() + ".demand_mshr_miss_latency")
495 .desc("number of demand (read+write) MSHR miss cycles")
496 .flags(total
| nozero
| nonan
)
498 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
499 for (int i
= 0; i
< system
->maxMasters(); i
++) {
500 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
503 overallMshrMissLatency
504 .name(name() + ".overall_mshr_miss_latency")
505 .desc("number of overall MSHR miss cycles")
506 .flags(total
| nozero
| nonan
)
508 overallMshrMissLatency
=
509 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
510 for (int i
= 0; i
< system
->maxMasters(); i
++) {
511 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
514 // MSHR uncacheable statistics
515 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
516 MemCmd
cmd(access_idx
);
517 const string
&cstr
= cmd
.toString();
519 mshr_uncacheable
[access_idx
]
520 .init(system
->maxMasters())
521 .name(name() + "." + cstr
+ "_mshr_uncacheable")
522 .desc("number of " + cstr
+ " MSHR uncacheable")
523 .flags(total
| nozero
| nonan
)
525 for (int i
= 0; i
< system
->maxMasters(); i
++) {
526 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
530 overallMshrUncacheable
531 .name(name() + ".overall_mshr_uncacheable_misses")
532 .desc("number of overall MSHR uncacheable misses")
533 .flags(total
| nozero
| nonan
)
535 overallMshrUncacheable
=
536 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
537 for (int i
= 0; i
< system
->maxMasters(); i
++) {
538 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
541 // MSHR miss latency statistics
542 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
543 MemCmd
cmd(access_idx
);
544 const string
&cstr
= cmd
.toString();
546 mshr_uncacheable_lat
[access_idx
]
547 .init(system
->maxMasters())
548 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
549 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
550 .flags(total
| nozero
| nonan
)
552 for (int i
= 0; i
< system
->maxMasters(); i
++) {
553 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
557 overallMshrUncacheableLatency
558 .name(name() + ".overall_mshr_uncacheable_latency")
559 .desc("number of overall MSHR uncacheable cycles")
560 .flags(total
| nozero
| nonan
)
562 overallMshrUncacheableLatency
=
563 SUM_DEMAND(mshr_uncacheable_lat
) +
564 SUM_NON_DEMAND(mshr_uncacheable_lat
);
565 for (int i
= 0; i
< system
->maxMasters(); i
++) {
566 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
570 // MSHR access formulas
571 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
572 MemCmd
cmd(access_idx
);
573 const string
&cstr
= cmd
.toString();
575 mshrAccesses
[access_idx
]
576 .name(name() + "." + cstr
+ "_mshr_accesses")
577 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
578 .flags(total
| nozero
| nonan
)
580 mshrAccesses
[access_idx
] =
581 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
582 + mshr_uncacheable
[access_idx
];
586 .name(name() + ".demand_mshr_accesses")
587 .desc("number of demand (read+write) mshr accesses")
588 .flags(total
| nozero
| nonan
)
590 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
593 .name(name() + ".overall_mshr_accesses")
594 .desc("number of overall (read+write) mshr accesses")
595 .flags(total
| nozero
| nonan
)
597 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
598 + overallMshrUncacheable
;
601 // MSHR miss rate formulas
602 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
603 MemCmd
cmd(access_idx
);
604 const string
&cstr
= cmd
.toString();
606 mshrMissRate
[access_idx
]
607 .name(name() + "." + cstr
+ "_mshr_miss_rate")
608 .desc("mshr miss rate for " + cstr
+ " accesses")
609 .flags(total
| nozero
| nonan
)
611 mshrMissRate
[access_idx
] =
612 mshr_misses
[access_idx
] / accesses
[access_idx
];
614 for (int i
= 0; i
< system
->maxMasters(); i
++) {
615 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
620 .name(name() + ".demand_mshr_miss_rate")
621 .desc("mshr miss rate for demand accesses")
622 .flags(total
| nozero
| nonan
)
624 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
625 for (int i
= 0; i
< system
->maxMasters(); i
++) {
626 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
630 .name(name() + ".overall_mshr_miss_rate")
631 .desc("mshr miss rate for overall accesses")
632 .flags(total
| nozero
| nonan
)
634 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
635 for (int i
= 0; i
< system
->maxMasters(); i
++) {
636 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
639 // mshrMiss latency formulas
640 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
641 MemCmd
cmd(access_idx
);
642 const string
&cstr
= cmd
.toString();
644 avgMshrMissLatency
[access_idx
]
645 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
646 .desc("average " + cstr
+ " mshr miss latency")
647 .flags(total
| nozero
| nonan
)
649 avgMshrMissLatency
[access_idx
] =
650 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
652 for (int i
= 0; i
< system
->maxMasters(); i
++) {
653 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
657 demandAvgMshrMissLatency
658 .name(name() + ".demand_avg_mshr_miss_latency")
659 .desc("average overall mshr miss latency")
660 .flags(total
| nozero
| nonan
)
662 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
663 for (int i
= 0; i
< system
->maxMasters(); i
++) {
664 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
667 overallAvgMshrMissLatency
668 .name(name() + ".overall_avg_mshr_miss_latency")
669 .desc("average overall mshr miss latency")
670 .flags(total
| nozero
| nonan
)
672 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
673 for (int i
= 0; i
< system
->maxMasters(); i
++) {
674 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
677 // mshrUncacheable latency formulas
678 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
679 MemCmd
cmd(access_idx
);
680 const string
&cstr
= cmd
.toString();
682 avgMshrUncacheableLatency
[access_idx
]
683 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
684 .desc("average " + cstr
+ " mshr uncacheable latency")
685 .flags(total
| nozero
| nonan
)
687 avgMshrUncacheableLatency
[access_idx
] =
688 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
690 for (int i
= 0; i
< system
->maxMasters(); i
++) {
691 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
695 overallAvgMshrUncacheableLatency
696 .name(name() + ".overall_avg_mshr_uncacheable_latency")
697 .desc("average overall mshr uncacheable latency")
698 .flags(total
| nozero
| nonan
)
700 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
701 for (int i
= 0; i
< system
->maxMasters(); i
++) {
702 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
706 .init(system
->maxMasters())
707 .name(name() + ".mshr_cap_events")
708 .desc("number of times MSHR cap was activated")
709 .flags(total
| nozero
| nonan
)
711 for (int i
= 0; i
< system
->maxMasters(); i
++) {
712 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
715 //software prefetching stats
716 soft_prefetch_mshr_full
717 .init(system
->maxMasters())
718 .name(name() + ".soft_prefetch_mshr_full")
719 .desc("number of mshr full events for SW prefetching instrutions")
720 .flags(total
| nozero
| nonan
)
722 for (int i
= 0; i
< system
->maxMasters(); i
++) {
723 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
726 mshr_no_allocate_misses
727 .name(name() +".no_allocate_misses")
728 .desc("Number of misses that were no-allocate")
734 BaseCache::drain(Event
*de
)
736 int count
= memSidePort
->drain(de
) + cpuSidePort
->drain(de
);
742 changeState(SimObject::Draining
);
746 changeState(SimObject::Drained
);