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 "debug/Drain.hh"
52 #include "mem/cache/base.hh"
53 #include "mem/cache/mshr.hh"
54 #include "sim/full_system.hh"
58 BaseCache::CacheSlavePort::CacheSlavePort(const std::string
&_name
,
60 const std::string
&_label
)
61 : QueuedSlavePort(_name
, _cache
, queue
), queue(*_cache
, *this, _label
),
62 blocked(false), mustSendRetry(false), sendRetryEvent(this)
66 BaseCache::BaseCache(const Params
*p
)
68 mshrQueue("MSHRs", p
->mshrs
, 4, MSHRQueue_MSHRs
),
69 writeBuffer("write buffer", p
->write_buffers
, p
->mshrs
+1000,
70 MSHRQueue_WriteBuffer
),
71 blkSize(p
->block_size
),
72 hitLatency(p
->hit_latency
),
73 responseLatency(p
->response_latency
),
74 numTarget(p
->tgts_per_mshr
),
75 forwardSnoops(p
->forward_snoops
),
76 isTopLevel(p
->is_top_level
),
79 missCount(p
->max_miss_count
),
81 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
87 BaseCache::CacheSlavePort::setBlocked()
90 DPRINTF(CachePort
, "Cache port %s blocking new requests\n", name());
95 BaseCache::CacheSlavePort::clearBlocked()
98 DPRINTF(CachePort
, "Cache port %s accepting new requests\n", name());
101 DPRINTF(CachePort
, "Cache port %s sending retry\n", name());
102 mustSendRetry
= false;
103 // @TODO: need to find a better time (next bus cycle?)
104 owner
.schedule(sendRetryEvent
, curTick() + 1);
112 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
113 fatal("Cache ports on %s are not connected\n", name());
114 cpuSidePort
->sendRangeChange();
118 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
120 if (if_name
== "mem_side") {
123 return MemObject::getMasterPort(if_name
, idx
);
128 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
130 if (if_name
== "cpu_side") {
133 return MemObject::getSlavePort(if_name
, idx
);
138 BaseCache::regStats()
140 using namespace Stats
;
143 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
144 MemCmd
cmd(access_idx
);
145 const string
&cstr
= cmd
.toString();
148 .init(system
->maxMasters())
149 .name(name() + "." + cstr
+ "_hits")
150 .desc("number of " + cstr
+ " hits")
151 .flags(total
| nozero
| nonan
)
153 for (int i
= 0; i
< system
->maxMasters(); i
++) {
154 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
158 // These macros make it easier to sum the right subset of commands and
159 // to change the subset of commands that are considered "demand" vs
161 #define SUM_DEMAND(s) \
162 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
164 // should writebacks be included here? prior code was inconsistent...
165 #define SUM_NON_DEMAND(s) \
166 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
169 .name(name() + ".demand_hits")
170 .desc("number of demand (read+write) hits")
171 .flags(total
| nozero
| nonan
)
173 demandHits
= SUM_DEMAND(hits
);
174 for (int i
= 0; i
< system
->maxMasters(); i
++) {
175 demandHits
.subname(i
, system
->getMasterName(i
));
179 .name(name() + ".overall_hits")
180 .desc("number of overall hits")
181 .flags(total
| nozero
| nonan
)
183 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
184 for (int i
= 0; i
< system
->maxMasters(); i
++) {
185 overallHits
.subname(i
, system
->getMasterName(i
));
189 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
190 MemCmd
cmd(access_idx
);
191 const string
&cstr
= cmd
.toString();
194 .init(system
->maxMasters())
195 .name(name() + "." + cstr
+ "_misses")
196 .desc("number of " + cstr
+ " misses")
197 .flags(total
| nozero
| nonan
)
199 for (int i
= 0; i
< system
->maxMasters(); i
++) {
200 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
205 .name(name() + ".demand_misses")
206 .desc("number of demand (read+write) misses")
207 .flags(total
| nozero
| nonan
)
209 demandMisses
= SUM_DEMAND(misses
);
210 for (int i
= 0; i
< system
->maxMasters(); i
++) {
211 demandMisses
.subname(i
, system
->getMasterName(i
));
215 .name(name() + ".overall_misses")
216 .desc("number of overall misses")
217 .flags(total
| nozero
| nonan
)
219 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
220 for (int i
= 0; i
< system
->maxMasters(); i
++) {
221 overallMisses
.subname(i
, system
->getMasterName(i
));
224 // Miss latency statistics
225 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
226 MemCmd
cmd(access_idx
);
227 const string
&cstr
= cmd
.toString();
229 missLatency
[access_idx
]
230 .init(system
->maxMasters())
231 .name(name() + "." + cstr
+ "_miss_latency")
232 .desc("number of " + cstr
+ " miss cycles")
233 .flags(total
| nozero
| nonan
)
235 for (int i
= 0; i
< system
->maxMasters(); i
++) {
236 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
241 .name(name() + ".demand_miss_latency")
242 .desc("number of demand (read+write) miss cycles")
243 .flags(total
| nozero
| nonan
)
245 demandMissLatency
= SUM_DEMAND(missLatency
);
246 for (int i
= 0; i
< system
->maxMasters(); i
++) {
247 demandMissLatency
.subname(i
, system
->getMasterName(i
));
251 .name(name() + ".overall_miss_latency")
252 .desc("number of overall miss cycles")
253 .flags(total
| nozero
| nonan
)
255 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
256 for (int i
= 0; i
< system
->maxMasters(); i
++) {
257 overallMissLatency
.subname(i
, system
->getMasterName(i
));
261 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
262 MemCmd
cmd(access_idx
);
263 const string
&cstr
= cmd
.toString();
266 .name(name() + "." + cstr
+ "_accesses")
267 .desc("number of " + cstr
+ " accesses(hits+misses)")
268 .flags(total
| nozero
| nonan
)
270 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
272 for (int i
= 0; i
< system
->maxMasters(); i
++) {
273 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
278 .name(name() + ".demand_accesses")
279 .desc("number of demand (read+write) accesses")
280 .flags(total
| nozero
| nonan
)
282 demandAccesses
= demandHits
+ demandMisses
;
283 for (int i
= 0; i
< system
->maxMasters(); i
++) {
284 demandAccesses
.subname(i
, system
->getMasterName(i
));
288 .name(name() + ".overall_accesses")
289 .desc("number of overall (read+write) accesses")
290 .flags(total
| nozero
| nonan
)
292 overallAccesses
= overallHits
+ overallMisses
;
293 for (int i
= 0; i
< system
->maxMasters(); i
++) {
294 overallAccesses
.subname(i
, system
->getMasterName(i
));
297 // miss rate formulas
298 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
299 MemCmd
cmd(access_idx
);
300 const string
&cstr
= cmd
.toString();
303 .name(name() + "." + cstr
+ "_miss_rate")
304 .desc("miss rate for " + cstr
+ " accesses")
305 .flags(total
| nozero
| nonan
)
307 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
309 for (int i
= 0; i
< system
->maxMasters(); i
++) {
310 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
315 .name(name() + ".demand_miss_rate")
316 .desc("miss rate for demand accesses")
317 .flags(total
| nozero
| nonan
)
319 demandMissRate
= demandMisses
/ demandAccesses
;
320 for (int i
= 0; i
< system
->maxMasters(); i
++) {
321 demandMissRate
.subname(i
, system
->getMasterName(i
));
325 .name(name() + ".overall_miss_rate")
326 .desc("miss rate for overall accesses")
327 .flags(total
| nozero
| nonan
)
329 overallMissRate
= overallMisses
/ overallAccesses
;
330 for (int i
= 0; i
< system
->maxMasters(); i
++) {
331 overallMissRate
.subname(i
, system
->getMasterName(i
));
334 // miss latency formulas
335 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
336 MemCmd
cmd(access_idx
);
337 const string
&cstr
= cmd
.toString();
339 avgMissLatency
[access_idx
]
340 .name(name() + "." + cstr
+ "_avg_miss_latency")
341 .desc("average " + cstr
+ " miss latency")
342 .flags(total
| nozero
| nonan
)
344 avgMissLatency
[access_idx
] =
345 missLatency
[access_idx
] / misses
[access_idx
];
347 for (int i
= 0; i
< system
->maxMasters(); i
++) {
348 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
353 .name(name() + ".demand_avg_miss_latency")
354 .desc("average overall miss latency")
355 .flags(total
| nozero
| nonan
)
357 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
358 for (int i
= 0; i
< system
->maxMasters(); i
++) {
359 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
362 overallAvgMissLatency
363 .name(name() + ".overall_avg_miss_latency")
364 .desc("average overall miss latency")
365 .flags(total
| nozero
| nonan
)
367 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
368 for (int i
= 0; i
< system
->maxMasters(); i
++) {
369 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
372 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
374 .name(name() + ".blocked_cycles")
375 .desc("number of cycles access was blocked")
376 .subname(Blocked_NoMSHRs
, "no_mshrs")
377 .subname(Blocked_NoTargets
, "no_targets")
381 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
383 .name(name() + ".blocked")
384 .desc("number of cycles access was blocked")
385 .subname(Blocked_NoMSHRs
, "no_mshrs")
386 .subname(Blocked_NoTargets
, "no_targets")
390 .name(name() + ".avg_blocked_cycles")
391 .desc("average number of cycles each access was blocked")
392 .subname(Blocked_NoMSHRs
, "no_mshrs")
393 .subname(Blocked_NoTargets
, "no_targets")
396 avg_blocked
= blocked_cycles
/ blocked_causes
;
399 .name(name() + ".fast_writes")
400 .desc("number of fast writes performed")
404 .name(name() + ".cache_copies")
405 .desc("number of cache copies performed")
409 .init(system
->maxMasters())
410 .name(name() + ".writebacks")
411 .desc("number of writebacks")
412 .flags(total
| nozero
| nonan
)
414 for (int i
= 0; i
< system
->maxMasters(); i
++) {
415 writebacks
.subname(i
, system
->getMasterName(i
));
419 // MSHR hit statistics
420 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
421 MemCmd
cmd(access_idx
);
422 const string
&cstr
= cmd
.toString();
424 mshr_hits
[access_idx
]
425 .init(system
->maxMasters())
426 .name(name() + "." + cstr
+ "_mshr_hits")
427 .desc("number of " + cstr
+ " MSHR hits")
428 .flags(total
| nozero
| nonan
)
430 for (int i
= 0; i
< system
->maxMasters(); i
++) {
431 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
436 .name(name() + ".demand_mshr_hits")
437 .desc("number of demand (read+write) MSHR hits")
438 .flags(total
| nozero
| nonan
)
440 demandMshrHits
= SUM_DEMAND(mshr_hits
);
441 for (int i
= 0; i
< system
->maxMasters(); i
++) {
442 demandMshrHits
.subname(i
, system
->getMasterName(i
));
446 .name(name() + ".overall_mshr_hits")
447 .desc("number of overall MSHR hits")
448 .flags(total
| nozero
| nonan
)
450 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
451 for (int i
= 0; i
< system
->maxMasters(); i
++) {
452 overallMshrHits
.subname(i
, system
->getMasterName(i
));
455 // MSHR miss statistics
456 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
457 MemCmd
cmd(access_idx
);
458 const string
&cstr
= cmd
.toString();
460 mshr_misses
[access_idx
]
461 .init(system
->maxMasters())
462 .name(name() + "." + cstr
+ "_mshr_misses")
463 .desc("number of " + cstr
+ " MSHR misses")
464 .flags(total
| nozero
| nonan
)
466 for (int i
= 0; i
< system
->maxMasters(); i
++) {
467 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
472 .name(name() + ".demand_mshr_misses")
473 .desc("number of demand (read+write) MSHR misses")
474 .flags(total
| nozero
| nonan
)
476 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
477 for (int i
= 0; i
< system
->maxMasters(); i
++) {
478 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
482 .name(name() + ".overall_mshr_misses")
483 .desc("number of overall MSHR misses")
484 .flags(total
| nozero
| nonan
)
486 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
487 for (int i
= 0; i
< system
->maxMasters(); i
++) {
488 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
491 // MSHR miss latency statistics
492 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
493 MemCmd
cmd(access_idx
);
494 const string
&cstr
= cmd
.toString();
496 mshr_miss_latency
[access_idx
]
497 .init(system
->maxMasters())
498 .name(name() + "." + cstr
+ "_mshr_miss_latency")
499 .desc("number of " + cstr
+ " MSHR miss cycles")
500 .flags(total
| nozero
| nonan
)
502 for (int i
= 0; i
< system
->maxMasters(); i
++) {
503 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
507 demandMshrMissLatency
508 .name(name() + ".demand_mshr_miss_latency")
509 .desc("number of demand (read+write) MSHR miss cycles")
510 .flags(total
| nozero
| nonan
)
512 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
513 for (int i
= 0; i
< system
->maxMasters(); i
++) {
514 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
517 overallMshrMissLatency
518 .name(name() + ".overall_mshr_miss_latency")
519 .desc("number of overall MSHR miss cycles")
520 .flags(total
| nozero
| nonan
)
522 overallMshrMissLatency
=
523 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
524 for (int i
= 0; i
< system
->maxMasters(); i
++) {
525 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
528 // MSHR uncacheable statistics
529 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
530 MemCmd
cmd(access_idx
);
531 const string
&cstr
= cmd
.toString();
533 mshr_uncacheable
[access_idx
]
534 .init(system
->maxMasters())
535 .name(name() + "." + cstr
+ "_mshr_uncacheable")
536 .desc("number of " + cstr
+ " MSHR uncacheable")
537 .flags(total
| nozero
| nonan
)
539 for (int i
= 0; i
< system
->maxMasters(); i
++) {
540 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
544 overallMshrUncacheable
545 .name(name() + ".overall_mshr_uncacheable_misses")
546 .desc("number of overall MSHR uncacheable misses")
547 .flags(total
| nozero
| nonan
)
549 overallMshrUncacheable
=
550 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
551 for (int i
= 0; i
< system
->maxMasters(); i
++) {
552 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
555 // MSHR miss latency statistics
556 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
557 MemCmd
cmd(access_idx
);
558 const string
&cstr
= cmd
.toString();
560 mshr_uncacheable_lat
[access_idx
]
561 .init(system
->maxMasters())
562 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
563 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
564 .flags(total
| nozero
| nonan
)
566 for (int i
= 0; i
< system
->maxMasters(); i
++) {
567 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
571 overallMshrUncacheableLatency
572 .name(name() + ".overall_mshr_uncacheable_latency")
573 .desc("number of overall MSHR uncacheable cycles")
574 .flags(total
| nozero
| nonan
)
576 overallMshrUncacheableLatency
=
577 SUM_DEMAND(mshr_uncacheable_lat
) +
578 SUM_NON_DEMAND(mshr_uncacheable_lat
);
579 for (int i
= 0; i
< system
->maxMasters(); i
++) {
580 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
584 // MSHR access formulas
585 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
586 MemCmd
cmd(access_idx
);
587 const string
&cstr
= cmd
.toString();
589 mshrAccesses
[access_idx
]
590 .name(name() + "." + cstr
+ "_mshr_accesses")
591 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
592 .flags(total
| nozero
| nonan
)
594 mshrAccesses
[access_idx
] =
595 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
596 + mshr_uncacheable
[access_idx
];
600 .name(name() + ".demand_mshr_accesses")
601 .desc("number of demand (read+write) mshr accesses")
602 .flags(total
| nozero
| nonan
)
604 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
607 .name(name() + ".overall_mshr_accesses")
608 .desc("number of overall (read+write) mshr accesses")
609 .flags(total
| nozero
| nonan
)
611 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
612 + overallMshrUncacheable
;
615 // MSHR miss rate 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 mshrMissRate
[access_idx
]
621 .name(name() + "." + cstr
+ "_mshr_miss_rate")
622 .desc("mshr miss rate for " + cstr
+ " accesses")
623 .flags(total
| nozero
| nonan
)
625 mshrMissRate
[access_idx
] =
626 mshr_misses
[access_idx
] / accesses
[access_idx
];
628 for (int i
= 0; i
< system
->maxMasters(); i
++) {
629 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
634 .name(name() + ".demand_mshr_miss_rate")
635 .desc("mshr miss rate for demand accesses")
636 .flags(total
| nozero
| nonan
)
638 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
639 for (int i
= 0; i
< system
->maxMasters(); i
++) {
640 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
644 .name(name() + ".overall_mshr_miss_rate")
645 .desc("mshr miss rate for overall accesses")
646 .flags(total
| nozero
| nonan
)
648 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
649 for (int i
= 0; i
< system
->maxMasters(); i
++) {
650 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
653 // mshrMiss latency formulas
654 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
655 MemCmd
cmd(access_idx
);
656 const string
&cstr
= cmd
.toString();
658 avgMshrMissLatency
[access_idx
]
659 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
660 .desc("average " + cstr
+ " mshr miss latency")
661 .flags(total
| nozero
| nonan
)
663 avgMshrMissLatency
[access_idx
] =
664 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
666 for (int i
= 0; i
< system
->maxMasters(); i
++) {
667 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
671 demandAvgMshrMissLatency
672 .name(name() + ".demand_avg_mshr_miss_latency")
673 .desc("average overall mshr miss latency")
674 .flags(total
| nozero
| nonan
)
676 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
677 for (int i
= 0; i
< system
->maxMasters(); i
++) {
678 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
681 overallAvgMshrMissLatency
682 .name(name() + ".overall_avg_mshr_miss_latency")
683 .desc("average overall mshr miss latency")
684 .flags(total
| nozero
| nonan
)
686 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
687 for (int i
= 0; i
< system
->maxMasters(); i
++) {
688 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
691 // mshrUncacheable latency formulas
692 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
693 MemCmd
cmd(access_idx
);
694 const string
&cstr
= cmd
.toString();
696 avgMshrUncacheableLatency
[access_idx
]
697 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
698 .desc("average " + cstr
+ " mshr uncacheable latency")
699 .flags(total
| nozero
| nonan
)
701 avgMshrUncacheableLatency
[access_idx
] =
702 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
704 for (int i
= 0; i
< system
->maxMasters(); i
++) {
705 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
709 overallAvgMshrUncacheableLatency
710 .name(name() + ".overall_avg_mshr_uncacheable_latency")
711 .desc("average overall mshr uncacheable latency")
712 .flags(total
| nozero
| nonan
)
714 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
715 for (int i
= 0; i
< system
->maxMasters(); i
++) {
716 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
720 .init(system
->maxMasters())
721 .name(name() + ".mshr_cap_events")
722 .desc("number of times MSHR cap was activated")
723 .flags(total
| nozero
| nonan
)
725 for (int i
= 0; i
< system
->maxMasters(); i
++) {
726 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
729 //software prefetching stats
730 soft_prefetch_mshr_full
731 .init(system
->maxMasters())
732 .name(name() + ".soft_prefetch_mshr_full")
733 .desc("number of mshr full events for SW prefetching instrutions")
734 .flags(total
| nozero
| nonan
)
736 for (int i
= 0; i
< system
->maxMasters(); i
++) {
737 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
740 mshr_no_allocate_misses
741 .name(name() +".no_allocate_misses")
742 .desc("Number of misses that were no-allocate")
748 BaseCache::drain(DrainManager
*dm
)
750 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
751 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
757 setDrainState(Drainable::Draining
);
758 DPRINTF(Drain
, "Cache not drained\n");
762 setDrainState(Drainable::Drained
);