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
),
85 missCount(p
->max_miss_count
),
86 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
92 BaseCache::CacheSlavePort::setBlocked()
95 DPRINTF(CachePort
, "Port is blocking new requests\n");
97 // if we already scheduled a retry in this cycle, but it has not yet
98 // happened, cancel it
99 if (sendRetryEvent
.scheduled()) {
100 owner
.deschedule(sendRetryEvent
);
101 DPRINTF(CachePort
, "Port descheduled retry\n");
102 mustSendRetry
= true;
107 BaseCache::CacheSlavePort::clearBlocked()
110 DPRINTF(CachePort
, "Port is accepting new requests\n");
113 // @TODO: need to find a better time (next cycle?)
114 owner
.schedule(sendRetryEvent
, curTick() + 1);
119 BaseCache::CacheSlavePort::processSendRetry()
121 DPRINTF(CachePort
, "Port is sending retry\n");
123 // reset the flag and call retry
124 mustSendRetry
= false;
131 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
132 fatal("Cache ports on %s are not connected\n", name());
133 cpuSidePort
->sendRangeChange();
137 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
139 if (if_name
== "mem_side") {
142 return MemObject::getMasterPort(if_name
, idx
);
147 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
149 if (if_name
== "cpu_side") {
152 return MemObject::getSlavePort(if_name
, idx
);
157 BaseCache::inRange(Addr addr
) const
159 for (const auto& r
: addrRanges
) {
160 if (r
.contains(addr
)) {
168 BaseCache::regStats()
170 using namespace Stats
;
173 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
174 MemCmd
cmd(access_idx
);
175 const string
&cstr
= cmd
.toString();
178 .init(system
->maxMasters())
179 .name(name() + "." + cstr
+ "_hits")
180 .desc("number of " + cstr
+ " hits")
181 .flags(total
| nozero
| nonan
)
183 for (int i
= 0; i
< system
->maxMasters(); i
++) {
184 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
188 // These macros make it easier to sum the right subset of commands and
189 // to change the subset of commands that are considered "demand" vs
191 #define SUM_DEMAND(s) \
192 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
194 // should writebacks be included here? prior code was inconsistent...
195 #define SUM_NON_DEMAND(s) \
196 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
199 .name(name() + ".demand_hits")
200 .desc("number of demand (read+write) hits")
201 .flags(total
| nozero
| nonan
)
203 demandHits
= SUM_DEMAND(hits
);
204 for (int i
= 0; i
< system
->maxMasters(); i
++) {
205 demandHits
.subname(i
, system
->getMasterName(i
));
209 .name(name() + ".overall_hits")
210 .desc("number of overall hits")
211 .flags(total
| nozero
| nonan
)
213 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
214 for (int i
= 0; i
< system
->maxMasters(); i
++) {
215 overallHits
.subname(i
, system
->getMasterName(i
));
219 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
220 MemCmd
cmd(access_idx
);
221 const string
&cstr
= cmd
.toString();
224 .init(system
->maxMasters())
225 .name(name() + "." + cstr
+ "_misses")
226 .desc("number of " + cstr
+ " misses")
227 .flags(total
| nozero
| nonan
)
229 for (int i
= 0; i
< system
->maxMasters(); i
++) {
230 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
235 .name(name() + ".demand_misses")
236 .desc("number of demand (read+write) misses")
237 .flags(total
| nozero
| nonan
)
239 demandMisses
= SUM_DEMAND(misses
);
240 for (int i
= 0; i
< system
->maxMasters(); i
++) {
241 demandMisses
.subname(i
, system
->getMasterName(i
));
245 .name(name() + ".overall_misses")
246 .desc("number of overall misses")
247 .flags(total
| nozero
| nonan
)
249 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
250 for (int i
= 0; i
< system
->maxMasters(); i
++) {
251 overallMisses
.subname(i
, system
->getMasterName(i
));
254 // Miss latency statistics
255 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
256 MemCmd
cmd(access_idx
);
257 const string
&cstr
= cmd
.toString();
259 missLatency
[access_idx
]
260 .init(system
->maxMasters())
261 .name(name() + "." + cstr
+ "_miss_latency")
262 .desc("number of " + cstr
+ " miss cycles")
263 .flags(total
| nozero
| nonan
)
265 for (int i
= 0; i
< system
->maxMasters(); i
++) {
266 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
271 .name(name() + ".demand_miss_latency")
272 .desc("number of demand (read+write) miss cycles")
273 .flags(total
| nozero
| nonan
)
275 demandMissLatency
= SUM_DEMAND(missLatency
);
276 for (int i
= 0; i
< system
->maxMasters(); i
++) {
277 demandMissLatency
.subname(i
, system
->getMasterName(i
));
281 .name(name() + ".overall_miss_latency")
282 .desc("number of overall miss cycles")
283 .flags(total
| nozero
| nonan
)
285 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
286 for (int i
= 0; i
< system
->maxMasters(); i
++) {
287 overallMissLatency
.subname(i
, system
->getMasterName(i
));
291 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
292 MemCmd
cmd(access_idx
);
293 const string
&cstr
= cmd
.toString();
296 .name(name() + "." + cstr
+ "_accesses")
297 .desc("number of " + cstr
+ " accesses(hits+misses)")
298 .flags(total
| nozero
| nonan
)
300 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
302 for (int i
= 0; i
< system
->maxMasters(); i
++) {
303 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
308 .name(name() + ".demand_accesses")
309 .desc("number of demand (read+write) accesses")
310 .flags(total
| nozero
| nonan
)
312 demandAccesses
= demandHits
+ demandMisses
;
313 for (int i
= 0; i
< system
->maxMasters(); i
++) {
314 demandAccesses
.subname(i
, system
->getMasterName(i
));
318 .name(name() + ".overall_accesses")
319 .desc("number of overall (read+write) accesses")
320 .flags(total
| nozero
| nonan
)
322 overallAccesses
= overallHits
+ overallMisses
;
323 for (int i
= 0; i
< system
->maxMasters(); i
++) {
324 overallAccesses
.subname(i
, system
->getMasterName(i
));
327 // miss rate formulas
328 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
329 MemCmd
cmd(access_idx
);
330 const string
&cstr
= cmd
.toString();
333 .name(name() + "." + cstr
+ "_miss_rate")
334 .desc("miss rate for " + cstr
+ " accesses")
335 .flags(total
| nozero
| nonan
)
337 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
339 for (int i
= 0; i
< system
->maxMasters(); i
++) {
340 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
345 .name(name() + ".demand_miss_rate")
346 .desc("miss rate for demand accesses")
347 .flags(total
| nozero
| nonan
)
349 demandMissRate
= demandMisses
/ demandAccesses
;
350 for (int i
= 0; i
< system
->maxMasters(); i
++) {
351 demandMissRate
.subname(i
, system
->getMasterName(i
));
355 .name(name() + ".overall_miss_rate")
356 .desc("miss rate for overall accesses")
357 .flags(total
| nozero
| nonan
)
359 overallMissRate
= overallMisses
/ overallAccesses
;
360 for (int i
= 0; i
< system
->maxMasters(); i
++) {
361 overallMissRate
.subname(i
, system
->getMasterName(i
));
364 // miss latency formulas
365 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
366 MemCmd
cmd(access_idx
);
367 const string
&cstr
= cmd
.toString();
369 avgMissLatency
[access_idx
]
370 .name(name() + "." + cstr
+ "_avg_miss_latency")
371 .desc("average " + cstr
+ " miss latency")
372 .flags(total
| nozero
| nonan
)
374 avgMissLatency
[access_idx
] =
375 missLatency
[access_idx
] / misses
[access_idx
];
377 for (int i
= 0; i
< system
->maxMasters(); i
++) {
378 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
383 .name(name() + ".demand_avg_miss_latency")
384 .desc("average overall miss latency")
385 .flags(total
| nozero
| nonan
)
387 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
388 for (int i
= 0; i
< system
->maxMasters(); i
++) {
389 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
392 overallAvgMissLatency
393 .name(name() + ".overall_avg_miss_latency")
394 .desc("average overall miss latency")
395 .flags(total
| nozero
| nonan
)
397 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
398 for (int i
= 0; i
< system
->maxMasters(); i
++) {
399 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
402 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
404 .name(name() + ".blocked_cycles")
405 .desc("number of cycles access was blocked")
406 .subname(Blocked_NoMSHRs
, "no_mshrs")
407 .subname(Blocked_NoTargets
, "no_targets")
411 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
413 .name(name() + ".blocked")
414 .desc("number of cycles access was blocked")
415 .subname(Blocked_NoMSHRs
, "no_mshrs")
416 .subname(Blocked_NoTargets
, "no_targets")
420 .name(name() + ".avg_blocked_cycles")
421 .desc("average number of cycles each access was blocked")
422 .subname(Blocked_NoMSHRs
, "no_mshrs")
423 .subname(Blocked_NoTargets
, "no_targets")
426 avg_blocked
= blocked_cycles
/ blocked_causes
;
429 .name(name() + ".fast_writes")
430 .desc("number of fast writes performed")
434 .name(name() + ".cache_copies")
435 .desc("number of cache copies performed")
439 .init(system
->maxMasters())
440 .name(name() + ".writebacks")
441 .desc("number of writebacks")
442 .flags(total
| nozero
| nonan
)
444 for (int i
= 0; i
< system
->maxMasters(); i
++) {
445 writebacks
.subname(i
, system
->getMasterName(i
));
449 // MSHR hit statistics
450 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
451 MemCmd
cmd(access_idx
);
452 const string
&cstr
= cmd
.toString();
454 mshr_hits
[access_idx
]
455 .init(system
->maxMasters())
456 .name(name() + "." + cstr
+ "_mshr_hits")
457 .desc("number of " + cstr
+ " MSHR hits")
458 .flags(total
| nozero
| nonan
)
460 for (int i
= 0; i
< system
->maxMasters(); i
++) {
461 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
466 .name(name() + ".demand_mshr_hits")
467 .desc("number of demand (read+write) MSHR hits")
468 .flags(total
| nozero
| nonan
)
470 demandMshrHits
= SUM_DEMAND(mshr_hits
);
471 for (int i
= 0; i
< system
->maxMasters(); i
++) {
472 demandMshrHits
.subname(i
, system
->getMasterName(i
));
476 .name(name() + ".overall_mshr_hits")
477 .desc("number of overall MSHR hits")
478 .flags(total
| nozero
| nonan
)
480 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
481 for (int i
= 0; i
< system
->maxMasters(); i
++) {
482 overallMshrHits
.subname(i
, system
->getMasterName(i
));
485 // MSHR miss statistics
486 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
487 MemCmd
cmd(access_idx
);
488 const string
&cstr
= cmd
.toString();
490 mshr_misses
[access_idx
]
491 .init(system
->maxMasters())
492 .name(name() + "." + cstr
+ "_mshr_misses")
493 .desc("number of " + cstr
+ " MSHR misses")
494 .flags(total
| nozero
| nonan
)
496 for (int i
= 0; i
< system
->maxMasters(); i
++) {
497 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
502 .name(name() + ".demand_mshr_misses")
503 .desc("number of demand (read+write) MSHR misses")
504 .flags(total
| nozero
| nonan
)
506 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
507 for (int i
= 0; i
< system
->maxMasters(); i
++) {
508 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
512 .name(name() + ".overall_mshr_misses")
513 .desc("number of overall MSHR misses")
514 .flags(total
| nozero
| nonan
)
516 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
517 for (int i
= 0; i
< system
->maxMasters(); i
++) {
518 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
521 // MSHR miss latency statistics
522 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
523 MemCmd
cmd(access_idx
);
524 const string
&cstr
= cmd
.toString();
526 mshr_miss_latency
[access_idx
]
527 .init(system
->maxMasters())
528 .name(name() + "." + cstr
+ "_mshr_miss_latency")
529 .desc("number of " + cstr
+ " MSHR miss cycles")
530 .flags(total
| nozero
| nonan
)
532 for (int i
= 0; i
< system
->maxMasters(); i
++) {
533 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
537 demandMshrMissLatency
538 .name(name() + ".demand_mshr_miss_latency")
539 .desc("number of demand (read+write) MSHR miss cycles")
540 .flags(total
| nozero
| nonan
)
542 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
543 for (int i
= 0; i
< system
->maxMasters(); i
++) {
544 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
547 overallMshrMissLatency
548 .name(name() + ".overall_mshr_miss_latency")
549 .desc("number of overall MSHR miss cycles")
550 .flags(total
| nozero
| nonan
)
552 overallMshrMissLatency
=
553 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
554 for (int i
= 0; i
< system
->maxMasters(); i
++) {
555 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
558 // MSHR uncacheable statistics
559 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
560 MemCmd
cmd(access_idx
);
561 const string
&cstr
= cmd
.toString();
563 mshr_uncacheable
[access_idx
]
564 .init(system
->maxMasters())
565 .name(name() + "." + cstr
+ "_mshr_uncacheable")
566 .desc("number of " + cstr
+ " MSHR uncacheable")
567 .flags(total
| nozero
| nonan
)
569 for (int i
= 0; i
< system
->maxMasters(); i
++) {
570 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
574 overallMshrUncacheable
575 .name(name() + ".overall_mshr_uncacheable_misses")
576 .desc("number of overall MSHR uncacheable misses")
577 .flags(total
| nozero
| nonan
)
579 overallMshrUncacheable
=
580 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
581 for (int i
= 0; i
< system
->maxMasters(); i
++) {
582 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
585 // MSHR miss latency statistics
586 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
587 MemCmd
cmd(access_idx
);
588 const string
&cstr
= cmd
.toString();
590 mshr_uncacheable_lat
[access_idx
]
591 .init(system
->maxMasters())
592 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
593 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
594 .flags(total
| nozero
| nonan
)
596 for (int i
= 0; i
< system
->maxMasters(); i
++) {
597 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
601 overallMshrUncacheableLatency
602 .name(name() + ".overall_mshr_uncacheable_latency")
603 .desc("number of overall MSHR uncacheable cycles")
604 .flags(total
| nozero
| nonan
)
606 overallMshrUncacheableLatency
=
607 SUM_DEMAND(mshr_uncacheable_lat
) +
608 SUM_NON_DEMAND(mshr_uncacheable_lat
);
609 for (int i
= 0; i
< system
->maxMasters(); i
++) {
610 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
614 // MSHR access 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 mshrAccesses
[access_idx
]
620 .name(name() + "." + cstr
+ "_mshr_accesses")
621 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
622 .flags(total
| nozero
| nonan
)
624 mshrAccesses
[access_idx
] =
625 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
626 + mshr_uncacheable
[access_idx
];
630 .name(name() + ".demand_mshr_accesses")
631 .desc("number of demand (read+write) mshr accesses")
632 .flags(total
| nozero
| nonan
)
634 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
637 .name(name() + ".overall_mshr_accesses")
638 .desc("number of overall (read+write) mshr accesses")
639 .flags(total
| nozero
| nonan
)
641 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
642 + overallMshrUncacheable
;
645 // MSHR miss rate formulas
646 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
647 MemCmd
cmd(access_idx
);
648 const string
&cstr
= cmd
.toString();
650 mshrMissRate
[access_idx
]
651 .name(name() + "." + cstr
+ "_mshr_miss_rate")
652 .desc("mshr miss rate for " + cstr
+ " accesses")
653 .flags(total
| nozero
| nonan
)
655 mshrMissRate
[access_idx
] =
656 mshr_misses
[access_idx
] / accesses
[access_idx
];
658 for (int i
= 0; i
< system
->maxMasters(); i
++) {
659 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
664 .name(name() + ".demand_mshr_miss_rate")
665 .desc("mshr miss rate for demand accesses")
666 .flags(total
| nozero
| nonan
)
668 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
669 for (int i
= 0; i
< system
->maxMasters(); i
++) {
670 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
674 .name(name() + ".overall_mshr_miss_rate")
675 .desc("mshr miss rate for overall accesses")
676 .flags(total
| nozero
| nonan
)
678 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
679 for (int i
= 0; i
< system
->maxMasters(); i
++) {
680 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
683 // mshrMiss latency formulas
684 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
685 MemCmd
cmd(access_idx
);
686 const string
&cstr
= cmd
.toString();
688 avgMshrMissLatency
[access_idx
]
689 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
690 .desc("average " + cstr
+ " mshr miss latency")
691 .flags(total
| nozero
| nonan
)
693 avgMshrMissLatency
[access_idx
] =
694 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
696 for (int i
= 0; i
< system
->maxMasters(); i
++) {
697 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
701 demandAvgMshrMissLatency
702 .name(name() + ".demand_avg_mshr_miss_latency")
703 .desc("average overall mshr miss latency")
704 .flags(total
| nozero
| nonan
)
706 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
707 for (int i
= 0; i
< system
->maxMasters(); i
++) {
708 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
711 overallAvgMshrMissLatency
712 .name(name() + ".overall_avg_mshr_miss_latency")
713 .desc("average overall mshr miss latency")
714 .flags(total
| nozero
| nonan
)
716 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
717 for (int i
= 0; i
< system
->maxMasters(); i
++) {
718 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
721 // mshrUncacheable latency formulas
722 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
723 MemCmd
cmd(access_idx
);
724 const string
&cstr
= cmd
.toString();
726 avgMshrUncacheableLatency
[access_idx
]
727 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
728 .desc("average " + cstr
+ " mshr uncacheable latency")
729 .flags(total
| nozero
| nonan
)
731 avgMshrUncacheableLatency
[access_idx
] =
732 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
734 for (int i
= 0; i
< system
->maxMasters(); i
++) {
735 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
739 overallAvgMshrUncacheableLatency
740 .name(name() + ".overall_avg_mshr_uncacheable_latency")
741 .desc("average overall mshr uncacheable latency")
742 .flags(total
| nozero
| nonan
)
744 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
745 for (int i
= 0; i
< system
->maxMasters(); i
++) {
746 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
750 .init(system
->maxMasters())
751 .name(name() + ".mshr_cap_events")
752 .desc("number of times MSHR cap was activated")
753 .flags(total
| nozero
| nonan
)
755 for (int i
= 0; i
< system
->maxMasters(); i
++) {
756 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
759 //software prefetching stats
760 soft_prefetch_mshr_full
761 .init(system
->maxMasters())
762 .name(name() + ".soft_prefetch_mshr_full")
763 .desc("number of mshr full events for SW prefetching instrutions")
764 .flags(total
| nozero
| nonan
)
766 for (int i
= 0; i
< system
->maxMasters(); i
++) {
767 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
770 mshr_no_allocate_misses
771 .name(name() +".no_allocate_misses")
772 .desc("Number of misses that were no-allocate")
778 BaseCache::drain(DrainManager
*dm
)
780 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
781 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
785 setDrainState(Drainable::Draining
);
786 DPRINTF(Drain
, "Cache not drained\n");
790 setDrainState(Drainable::Drained
);
795 BaseCacheParams::create()
799 return new Cache(this);