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
),
80 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
86 BaseCache::CacheSlavePort::setBlocked()
89 DPRINTF(CachePort
, "Cache port %s blocking new requests\n", name());
94 BaseCache::CacheSlavePort::clearBlocked()
97 DPRINTF(CachePort
, "Cache port %s accepting new requests\n", name());
100 DPRINTF(CachePort
, "Cache port %s sending retry\n", name());
101 mustSendRetry
= false;
102 // @TODO: need to find a better time (next bus cycle?)
103 owner
.schedule(sendRetryEvent
, curTick() + 1);
111 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
112 fatal("Cache ports on %s are not connected\n", name());
113 cpuSidePort
->sendRangeChange();
117 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
119 if (if_name
== "mem_side") {
122 return MemObject::getMasterPort(if_name
, idx
);
127 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
129 if (if_name
== "cpu_side") {
132 return MemObject::getSlavePort(if_name
, idx
);
137 BaseCache::regStats()
139 using namespace Stats
;
142 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
143 MemCmd
cmd(access_idx
);
144 const string
&cstr
= cmd
.toString();
147 .init(system
->maxMasters())
148 .name(name() + "." + cstr
+ "_hits")
149 .desc("number of " + cstr
+ " hits")
150 .flags(total
| nozero
| nonan
)
152 for (int i
= 0; i
< system
->maxMasters(); i
++) {
153 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
157 // These macros make it easier to sum the right subset of commands and
158 // to change the subset of commands that are considered "demand" vs
160 #define SUM_DEMAND(s) \
161 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
163 // should writebacks be included here? prior code was inconsistent...
164 #define SUM_NON_DEMAND(s) \
165 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
168 .name(name() + ".demand_hits")
169 .desc("number of demand (read+write) hits")
170 .flags(total
| nozero
| nonan
)
172 demandHits
= SUM_DEMAND(hits
);
173 for (int i
= 0; i
< system
->maxMasters(); i
++) {
174 demandHits
.subname(i
, system
->getMasterName(i
));
178 .name(name() + ".overall_hits")
179 .desc("number of overall hits")
180 .flags(total
| nozero
| nonan
)
182 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
183 for (int i
= 0; i
< system
->maxMasters(); i
++) {
184 overallHits
.subname(i
, system
->getMasterName(i
));
188 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
189 MemCmd
cmd(access_idx
);
190 const string
&cstr
= cmd
.toString();
193 .init(system
->maxMasters())
194 .name(name() + "." + cstr
+ "_misses")
195 .desc("number of " + cstr
+ " misses")
196 .flags(total
| nozero
| nonan
)
198 for (int i
= 0; i
< system
->maxMasters(); i
++) {
199 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
204 .name(name() + ".demand_misses")
205 .desc("number of demand (read+write) misses")
206 .flags(total
| nozero
| nonan
)
208 demandMisses
= SUM_DEMAND(misses
);
209 for (int i
= 0; i
< system
->maxMasters(); i
++) {
210 demandMisses
.subname(i
, system
->getMasterName(i
));
214 .name(name() + ".overall_misses")
215 .desc("number of overall misses")
216 .flags(total
| nozero
| nonan
)
218 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
219 for (int i
= 0; i
< system
->maxMasters(); i
++) {
220 overallMisses
.subname(i
, system
->getMasterName(i
));
223 // Miss latency statistics
224 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
225 MemCmd
cmd(access_idx
);
226 const string
&cstr
= cmd
.toString();
228 missLatency
[access_idx
]
229 .init(system
->maxMasters())
230 .name(name() + "." + cstr
+ "_miss_latency")
231 .desc("number of " + cstr
+ " miss cycles")
232 .flags(total
| nozero
| nonan
)
234 for (int i
= 0; i
< system
->maxMasters(); i
++) {
235 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
240 .name(name() + ".demand_miss_latency")
241 .desc("number of demand (read+write) miss cycles")
242 .flags(total
| nozero
| nonan
)
244 demandMissLatency
= SUM_DEMAND(missLatency
);
245 for (int i
= 0; i
< system
->maxMasters(); i
++) {
246 demandMissLatency
.subname(i
, system
->getMasterName(i
));
250 .name(name() + ".overall_miss_latency")
251 .desc("number of overall miss cycles")
252 .flags(total
| nozero
| nonan
)
254 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
255 for (int i
= 0; i
< system
->maxMasters(); i
++) {
256 overallMissLatency
.subname(i
, system
->getMasterName(i
));
260 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
261 MemCmd
cmd(access_idx
);
262 const string
&cstr
= cmd
.toString();
265 .name(name() + "." + cstr
+ "_accesses")
266 .desc("number of " + cstr
+ " accesses(hits+misses)")
267 .flags(total
| nozero
| nonan
)
269 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
271 for (int i
= 0; i
< system
->maxMasters(); i
++) {
272 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
277 .name(name() + ".demand_accesses")
278 .desc("number of demand (read+write) accesses")
279 .flags(total
| nozero
| nonan
)
281 demandAccesses
= demandHits
+ demandMisses
;
282 for (int i
= 0; i
< system
->maxMasters(); i
++) {
283 demandAccesses
.subname(i
, system
->getMasterName(i
));
287 .name(name() + ".overall_accesses")
288 .desc("number of overall (read+write) accesses")
289 .flags(total
| nozero
| nonan
)
291 overallAccesses
= overallHits
+ overallMisses
;
292 for (int i
= 0; i
< system
->maxMasters(); i
++) {
293 overallAccesses
.subname(i
, system
->getMasterName(i
));
296 // miss rate formulas
297 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
298 MemCmd
cmd(access_idx
);
299 const string
&cstr
= cmd
.toString();
302 .name(name() + "." + cstr
+ "_miss_rate")
303 .desc("miss rate for " + cstr
+ " accesses")
304 .flags(total
| nozero
| nonan
)
306 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
308 for (int i
= 0; i
< system
->maxMasters(); i
++) {
309 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
314 .name(name() + ".demand_miss_rate")
315 .desc("miss rate for demand accesses")
316 .flags(total
| nozero
| nonan
)
318 demandMissRate
= demandMisses
/ demandAccesses
;
319 for (int i
= 0; i
< system
->maxMasters(); i
++) {
320 demandMissRate
.subname(i
, system
->getMasterName(i
));
324 .name(name() + ".overall_miss_rate")
325 .desc("miss rate for overall accesses")
326 .flags(total
| nozero
| nonan
)
328 overallMissRate
= overallMisses
/ overallAccesses
;
329 for (int i
= 0; i
< system
->maxMasters(); i
++) {
330 overallMissRate
.subname(i
, system
->getMasterName(i
));
333 // miss latency formulas
334 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
335 MemCmd
cmd(access_idx
);
336 const string
&cstr
= cmd
.toString();
338 avgMissLatency
[access_idx
]
339 .name(name() + "." + cstr
+ "_avg_miss_latency")
340 .desc("average " + cstr
+ " miss latency")
341 .flags(total
| nozero
| nonan
)
343 avgMissLatency
[access_idx
] =
344 missLatency
[access_idx
] / misses
[access_idx
];
346 for (int i
= 0; i
< system
->maxMasters(); i
++) {
347 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
352 .name(name() + ".demand_avg_miss_latency")
353 .desc("average overall miss latency")
354 .flags(total
| nozero
| nonan
)
356 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
357 for (int i
= 0; i
< system
->maxMasters(); i
++) {
358 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
361 overallAvgMissLatency
362 .name(name() + ".overall_avg_miss_latency")
363 .desc("average overall miss latency")
364 .flags(total
| nozero
| nonan
)
366 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
367 for (int i
= 0; i
< system
->maxMasters(); i
++) {
368 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
371 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
373 .name(name() + ".blocked_cycles")
374 .desc("number of cycles access was blocked")
375 .subname(Blocked_NoMSHRs
, "no_mshrs")
376 .subname(Blocked_NoTargets
, "no_targets")
380 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
382 .name(name() + ".blocked")
383 .desc("number of cycles access was blocked")
384 .subname(Blocked_NoMSHRs
, "no_mshrs")
385 .subname(Blocked_NoTargets
, "no_targets")
389 .name(name() + ".avg_blocked_cycles")
390 .desc("average number of cycles each access was blocked")
391 .subname(Blocked_NoMSHRs
, "no_mshrs")
392 .subname(Blocked_NoTargets
, "no_targets")
395 avg_blocked
= blocked_cycles
/ blocked_causes
;
398 .name(name() + ".fast_writes")
399 .desc("number of fast writes performed")
403 .name(name() + ".cache_copies")
404 .desc("number of cache copies performed")
408 .init(system
->maxMasters())
409 .name(name() + ".writebacks")
410 .desc("number of writebacks")
411 .flags(total
| nozero
| nonan
)
413 for (int i
= 0; i
< system
->maxMasters(); i
++) {
414 writebacks
.subname(i
, system
->getMasterName(i
));
418 // MSHR hit statistics
419 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
420 MemCmd
cmd(access_idx
);
421 const string
&cstr
= cmd
.toString();
423 mshr_hits
[access_idx
]
424 .init(system
->maxMasters())
425 .name(name() + "." + cstr
+ "_mshr_hits")
426 .desc("number of " + cstr
+ " MSHR hits")
427 .flags(total
| nozero
| nonan
)
429 for (int i
= 0; i
< system
->maxMasters(); i
++) {
430 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
435 .name(name() + ".demand_mshr_hits")
436 .desc("number of demand (read+write) MSHR hits")
437 .flags(total
| nozero
| nonan
)
439 demandMshrHits
= SUM_DEMAND(mshr_hits
);
440 for (int i
= 0; i
< system
->maxMasters(); i
++) {
441 demandMshrHits
.subname(i
, system
->getMasterName(i
));
445 .name(name() + ".overall_mshr_hits")
446 .desc("number of overall MSHR hits")
447 .flags(total
| nozero
| nonan
)
449 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
450 for (int i
= 0; i
< system
->maxMasters(); i
++) {
451 overallMshrHits
.subname(i
, system
->getMasterName(i
));
454 // MSHR miss statistics
455 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
456 MemCmd
cmd(access_idx
);
457 const string
&cstr
= cmd
.toString();
459 mshr_misses
[access_idx
]
460 .init(system
->maxMasters())
461 .name(name() + "." + cstr
+ "_mshr_misses")
462 .desc("number of " + cstr
+ " MSHR misses")
463 .flags(total
| nozero
| nonan
)
465 for (int i
= 0; i
< system
->maxMasters(); i
++) {
466 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
471 .name(name() + ".demand_mshr_misses")
472 .desc("number of demand (read+write) MSHR misses")
473 .flags(total
| nozero
| nonan
)
475 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
476 for (int i
= 0; i
< system
->maxMasters(); i
++) {
477 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
481 .name(name() + ".overall_mshr_misses")
482 .desc("number of overall MSHR misses")
483 .flags(total
| nozero
| nonan
)
485 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
486 for (int i
= 0; i
< system
->maxMasters(); i
++) {
487 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
490 // MSHR miss latency statistics
491 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
492 MemCmd
cmd(access_idx
);
493 const string
&cstr
= cmd
.toString();
495 mshr_miss_latency
[access_idx
]
496 .init(system
->maxMasters())
497 .name(name() + "." + cstr
+ "_mshr_miss_latency")
498 .desc("number of " + cstr
+ " MSHR miss cycles")
499 .flags(total
| nozero
| nonan
)
501 for (int i
= 0; i
< system
->maxMasters(); i
++) {
502 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
506 demandMshrMissLatency
507 .name(name() + ".demand_mshr_miss_latency")
508 .desc("number of demand (read+write) MSHR miss cycles")
509 .flags(total
| nozero
| nonan
)
511 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
512 for (int i
= 0; i
< system
->maxMasters(); i
++) {
513 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
516 overallMshrMissLatency
517 .name(name() + ".overall_mshr_miss_latency")
518 .desc("number of overall MSHR miss cycles")
519 .flags(total
| nozero
| nonan
)
521 overallMshrMissLatency
=
522 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
523 for (int i
= 0; i
< system
->maxMasters(); i
++) {
524 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
527 // MSHR uncacheable statistics
528 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
529 MemCmd
cmd(access_idx
);
530 const string
&cstr
= cmd
.toString();
532 mshr_uncacheable
[access_idx
]
533 .init(system
->maxMasters())
534 .name(name() + "." + cstr
+ "_mshr_uncacheable")
535 .desc("number of " + cstr
+ " MSHR uncacheable")
536 .flags(total
| nozero
| nonan
)
538 for (int i
= 0; i
< system
->maxMasters(); i
++) {
539 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
543 overallMshrUncacheable
544 .name(name() + ".overall_mshr_uncacheable_misses")
545 .desc("number of overall MSHR uncacheable misses")
546 .flags(total
| nozero
| nonan
)
548 overallMshrUncacheable
=
549 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
550 for (int i
= 0; i
< system
->maxMasters(); i
++) {
551 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
554 // MSHR miss latency statistics
555 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
556 MemCmd
cmd(access_idx
);
557 const string
&cstr
= cmd
.toString();
559 mshr_uncacheable_lat
[access_idx
]
560 .init(system
->maxMasters())
561 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
562 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
563 .flags(total
| nozero
| nonan
)
565 for (int i
= 0; i
< system
->maxMasters(); i
++) {
566 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
570 overallMshrUncacheableLatency
571 .name(name() + ".overall_mshr_uncacheable_latency")
572 .desc("number of overall MSHR uncacheable cycles")
573 .flags(total
| nozero
| nonan
)
575 overallMshrUncacheableLatency
=
576 SUM_DEMAND(mshr_uncacheable_lat
) +
577 SUM_NON_DEMAND(mshr_uncacheable_lat
);
578 for (int i
= 0; i
< system
->maxMasters(); i
++) {
579 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
583 // MSHR access formulas
584 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
585 MemCmd
cmd(access_idx
);
586 const string
&cstr
= cmd
.toString();
588 mshrAccesses
[access_idx
]
589 .name(name() + "." + cstr
+ "_mshr_accesses")
590 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
591 .flags(total
| nozero
| nonan
)
593 mshrAccesses
[access_idx
] =
594 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
595 + mshr_uncacheable
[access_idx
];
599 .name(name() + ".demand_mshr_accesses")
600 .desc("number of demand (read+write) mshr accesses")
601 .flags(total
| nozero
| nonan
)
603 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
606 .name(name() + ".overall_mshr_accesses")
607 .desc("number of overall (read+write) mshr accesses")
608 .flags(total
| nozero
| nonan
)
610 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
611 + overallMshrUncacheable
;
614 // MSHR miss rate formulas
615 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
616 MemCmd
cmd(access_idx
);
617 const string
&cstr
= cmd
.toString();
619 mshrMissRate
[access_idx
]
620 .name(name() + "." + cstr
+ "_mshr_miss_rate")
621 .desc("mshr miss rate for " + cstr
+ " accesses")
622 .flags(total
| nozero
| nonan
)
624 mshrMissRate
[access_idx
] =
625 mshr_misses
[access_idx
] / accesses
[access_idx
];
627 for (int i
= 0; i
< system
->maxMasters(); i
++) {
628 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
633 .name(name() + ".demand_mshr_miss_rate")
634 .desc("mshr miss rate for demand accesses")
635 .flags(total
| nozero
| nonan
)
637 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
638 for (int i
= 0; i
< system
->maxMasters(); i
++) {
639 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
643 .name(name() + ".overall_mshr_miss_rate")
644 .desc("mshr miss rate for overall accesses")
645 .flags(total
| nozero
| nonan
)
647 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
648 for (int i
= 0; i
< system
->maxMasters(); i
++) {
649 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
652 // mshrMiss latency formulas
653 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
654 MemCmd
cmd(access_idx
);
655 const string
&cstr
= cmd
.toString();
657 avgMshrMissLatency
[access_idx
]
658 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
659 .desc("average " + cstr
+ " mshr miss latency")
660 .flags(total
| nozero
| nonan
)
662 avgMshrMissLatency
[access_idx
] =
663 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
665 for (int i
= 0; i
< system
->maxMasters(); i
++) {
666 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
670 demandAvgMshrMissLatency
671 .name(name() + ".demand_avg_mshr_miss_latency")
672 .desc("average overall mshr miss latency")
673 .flags(total
| nozero
| nonan
)
675 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
676 for (int i
= 0; i
< system
->maxMasters(); i
++) {
677 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
680 overallAvgMshrMissLatency
681 .name(name() + ".overall_avg_mshr_miss_latency")
682 .desc("average overall mshr miss latency")
683 .flags(total
| nozero
| nonan
)
685 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
686 for (int i
= 0; i
< system
->maxMasters(); i
++) {
687 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
690 // mshrUncacheable latency formulas
691 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
692 MemCmd
cmd(access_idx
);
693 const string
&cstr
= cmd
.toString();
695 avgMshrUncacheableLatency
[access_idx
]
696 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
697 .desc("average " + cstr
+ " mshr uncacheable latency")
698 .flags(total
| nozero
| nonan
)
700 avgMshrUncacheableLatency
[access_idx
] =
701 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
703 for (int i
= 0; i
< system
->maxMasters(); i
++) {
704 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
708 overallAvgMshrUncacheableLatency
709 .name(name() + ".overall_avg_mshr_uncacheable_latency")
710 .desc("average overall mshr uncacheable latency")
711 .flags(total
| nozero
| nonan
)
713 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
714 for (int i
= 0; i
< system
->maxMasters(); i
++) {
715 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
719 .init(system
->maxMasters())
720 .name(name() + ".mshr_cap_events")
721 .desc("number of times MSHR cap was activated")
722 .flags(total
| nozero
| nonan
)
724 for (int i
= 0; i
< system
->maxMasters(); i
++) {
725 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
728 //software prefetching stats
729 soft_prefetch_mshr_full
730 .init(system
->maxMasters())
731 .name(name() + ".soft_prefetch_mshr_full")
732 .desc("number of mshr full events for SW prefetching instrutions")
733 .flags(total
| nozero
| nonan
)
735 for (int i
= 0; i
< system
->maxMasters(); i
++) {
736 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
739 mshr_no_allocate_misses
740 .name(name() +".no_allocate_misses")
741 .desc("Number of misses that were no-allocate")
747 BaseCache::drain(DrainManager
*dm
)
749 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
750 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
754 setDrainState(Drainable::Draining
);
755 DPRINTF(Drain
, "Cache not drained\n");
759 setDrainState(Drainable::Drained
);