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, MSHRQueue_MSHRs
),
72 writeBuffer("write buffer", p
->write_buffers
, p
->mshrs
+1000,
73 MSHRQueue_WriteBuffer
),
74 blkSize(p
->system
->cacheLineSize()),
75 hitLatency(p
->hit_latency
),
76 responseLatency(p
->response_latency
),
77 numTarget(p
->tgts_per_mshr
),
78 forwardSnoops(p
->forward_snoops
),
79 isTopLevel(p
->is_top_level
),
83 missCount(p
->max_miss_count
),
84 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
90 BaseCache::CacheSlavePort::setBlocked()
93 DPRINTF(CachePort
, "Cache port %s blocking new requests\n", name());
95 // if we already scheduled a retry in this cycle, but it has not yet
96 // happened, cancel it
97 if (sendRetryEvent
.scheduled()) {
98 owner
.deschedule(sendRetryEvent
);
99 DPRINTF(CachePort
, "Cache port %s deschedule retry\n", name());
100 mustSendRetry
= true;
105 BaseCache::CacheSlavePort::clearBlocked()
108 DPRINTF(CachePort
, "Cache port %s accepting new requests\n", name());
111 // @TODO: need to find a better time (next bus cycle?)
112 owner
.schedule(sendRetryEvent
, curTick() + 1);
117 BaseCache::CacheSlavePort::processSendRetry()
119 DPRINTF(CachePort
, "Cache port %s sending retry\n", name());
121 // reset the flag and call retry
122 mustSendRetry
= false;
129 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
130 fatal("Cache ports on %s are not connected\n", name());
131 cpuSidePort
->sendRangeChange();
135 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
137 if (if_name
== "mem_side") {
140 return MemObject::getMasterPort(if_name
, idx
);
145 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
147 if (if_name
== "cpu_side") {
150 return MemObject::getSlavePort(if_name
, idx
);
155 BaseCache::regStats()
157 using namespace Stats
;
160 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
161 MemCmd
cmd(access_idx
);
162 const string
&cstr
= cmd
.toString();
165 .init(system
->maxMasters())
166 .name(name() + "." + cstr
+ "_hits")
167 .desc("number of " + cstr
+ " hits")
168 .flags(total
| nozero
| nonan
)
170 for (int i
= 0; i
< system
->maxMasters(); i
++) {
171 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
175 // These macros make it easier to sum the right subset of commands and
176 // to change the subset of commands that are considered "demand" vs
178 #define SUM_DEMAND(s) \
179 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
181 // should writebacks be included here? prior code was inconsistent...
182 #define SUM_NON_DEMAND(s) \
183 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
186 .name(name() + ".demand_hits")
187 .desc("number of demand (read+write) hits")
188 .flags(total
| nozero
| nonan
)
190 demandHits
= SUM_DEMAND(hits
);
191 for (int i
= 0; i
< system
->maxMasters(); i
++) {
192 demandHits
.subname(i
, system
->getMasterName(i
));
196 .name(name() + ".overall_hits")
197 .desc("number of overall hits")
198 .flags(total
| nozero
| nonan
)
200 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
201 for (int i
= 0; i
< system
->maxMasters(); i
++) {
202 overallHits
.subname(i
, system
->getMasterName(i
));
206 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
207 MemCmd
cmd(access_idx
);
208 const string
&cstr
= cmd
.toString();
211 .init(system
->maxMasters())
212 .name(name() + "." + cstr
+ "_misses")
213 .desc("number of " + cstr
+ " misses")
214 .flags(total
| nozero
| nonan
)
216 for (int i
= 0; i
< system
->maxMasters(); i
++) {
217 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
222 .name(name() + ".demand_misses")
223 .desc("number of demand (read+write) misses")
224 .flags(total
| nozero
| nonan
)
226 demandMisses
= SUM_DEMAND(misses
);
227 for (int i
= 0; i
< system
->maxMasters(); i
++) {
228 demandMisses
.subname(i
, system
->getMasterName(i
));
232 .name(name() + ".overall_misses")
233 .desc("number of overall misses")
234 .flags(total
| nozero
| nonan
)
236 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
237 for (int i
= 0; i
< system
->maxMasters(); i
++) {
238 overallMisses
.subname(i
, system
->getMasterName(i
));
241 // Miss latency statistics
242 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
243 MemCmd
cmd(access_idx
);
244 const string
&cstr
= cmd
.toString();
246 missLatency
[access_idx
]
247 .init(system
->maxMasters())
248 .name(name() + "." + cstr
+ "_miss_latency")
249 .desc("number of " + cstr
+ " miss cycles")
250 .flags(total
| nozero
| nonan
)
252 for (int i
= 0; i
< system
->maxMasters(); i
++) {
253 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
258 .name(name() + ".demand_miss_latency")
259 .desc("number of demand (read+write) miss cycles")
260 .flags(total
| nozero
| nonan
)
262 demandMissLatency
= SUM_DEMAND(missLatency
);
263 for (int i
= 0; i
< system
->maxMasters(); i
++) {
264 demandMissLatency
.subname(i
, system
->getMasterName(i
));
268 .name(name() + ".overall_miss_latency")
269 .desc("number of overall miss cycles")
270 .flags(total
| nozero
| nonan
)
272 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
273 for (int i
= 0; i
< system
->maxMasters(); i
++) {
274 overallMissLatency
.subname(i
, system
->getMasterName(i
));
278 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
279 MemCmd
cmd(access_idx
);
280 const string
&cstr
= cmd
.toString();
283 .name(name() + "." + cstr
+ "_accesses")
284 .desc("number of " + cstr
+ " accesses(hits+misses)")
285 .flags(total
| nozero
| nonan
)
287 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
289 for (int i
= 0; i
< system
->maxMasters(); i
++) {
290 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
295 .name(name() + ".demand_accesses")
296 .desc("number of demand (read+write) accesses")
297 .flags(total
| nozero
| nonan
)
299 demandAccesses
= demandHits
+ demandMisses
;
300 for (int i
= 0; i
< system
->maxMasters(); i
++) {
301 demandAccesses
.subname(i
, system
->getMasterName(i
));
305 .name(name() + ".overall_accesses")
306 .desc("number of overall (read+write) accesses")
307 .flags(total
| nozero
| nonan
)
309 overallAccesses
= overallHits
+ overallMisses
;
310 for (int i
= 0; i
< system
->maxMasters(); i
++) {
311 overallAccesses
.subname(i
, system
->getMasterName(i
));
314 // miss rate formulas
315 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
316 MemCmd
cmd(access_idx
);
317 const string
&cstr
= cmd
.toString();
320 .name(name() + "." + cstr
+ "_miss_rate")
321 .desc("miss rate for " + cstr
+ " accesses")
322 .flags(total
| nozero
| nonan
)
324 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
326 for (int i
= 0; i
< system
->maxMasters(); i
++) {
327 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
332 .name(name() + ".demand_miss_rate")
333 .desc("miss rate for demand accesses")
334 .flags(total
| nozero
| nonan
)
336 demandMissRate
= demandMisses
/ demandAccesses
;
337 for (int i
= 0; i
< system
->maxMasters(); i
++) {
338 demandMissRate
.subname(i
, system
->getMasterName(i
));
342 .name(name() + ".overall_miss_rate")
343 .desc("miss rate for overall accesses")
344 .flags(total
| nozero
| nonan
)
346 overallMissRate
= overallMisses
/ overallAccesses
;
347 for (int i
= 0; i
< system
->maxMasters(); i
++) {
348 overallMissRate
.subname(i
, system
->getMasterName(i
));
351 // miss latency formulas
352 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
353 MemCmd
cmd(access_idx
);
354 const string
&cstr
= cmd
.toString();
356 avgMissLatency
[access_idx
]
357 .name(name() + "." + cstr
+ "_avg_miss_latency")
358 .desc("average " + cstr
+ " miss latency")
359 .flags(total
| nozero
| nonan
)
361 avgMissLatency
[access_idx
] =
362 missLatency
[access_idx
] / misses
[access_idx
];
364 for (int i
= 0; i
< system
->maxMasters(); i
++) {
365 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
370 .name(name() + ".demand_avg_miss_latency")
371 .desc("average overall miss latency")
372 .flags(total
| nozero
| nonan
)
374 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
375 for (int i
= 0; i
< system
->maxMasters(); i
++) {
376 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
379 overallAvgMissLatency
380 .name(name() + ".overall_avg_miss_latency")
381 .desc("average overall miss latency")
382 .flags(total
| nozero
| nonan
)
384 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
385 for (int i
= 0; i
< system
->maxMasters(); i
++) {
386 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
389 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
391 .name(name() + ".blocked_cycles")
392 .desc("number of cycles access was blocked")
393 .subname(Blocked_NoMSHRs
, "no_mshrs")
394 .subname(Blocked_NoTargets
, "no_targets")
398 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
400 .name(name() + ".blocked")
401 .desc("number of cycles access was blocked")
402 .subname(Blocked_NoMSHRs
, "no_mshrs")
403 .subname(Blocked_NoTargets
, "no_targets")
407 .name(name() + ".avg_blocked_cycles")
408 .desc("average number of cycles each access was blocked")
409 .subname(Blocked_NoMSHRs
, "no_mshrs")
410 .subname(Blocked_NoTargets
, "no_targets")
413 avg_blocked
= blocked_cycles
/ blocked_causes
;
416 .name(name() + ".fast_writes")
417 .desc("number of fast writes performed")
421 .name(name() + ".cache_copies")
422 .desc("number of cache copies performed")
426 .init(system
->maxMasters())
427 .name(name() + ".writebacks")
428 .desc("number of writebacks")
429 .flags(total
| nozero
| nonan
)
431 for (int i
= 0; i
< system
->maxMasters(); i
++) {
432 writebacks
.subname(i
, system
->getMasterName(i
));
436 // MSHR hit statistics
437 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
438 MemCmd
cmd(access_idx
);
439 const string
&cstr
= cmd
.toString();
441 mshr_hits
[access_idx
]
442 .init(system
->maxMasters())
443 .name(name() + "." + cstr
+ "_mshr_hits")
444 .desc("number of " + cstr
+ " MSHR hits")
445 .flags(total
| nozero
| nonan
)
447 for (int i
= 0; i
< system
->maxMasters(); i
++) {
448 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
453 .name(name() + ".demand_mshr_hits")
454 .desc("number of demand (read+write) MSHR hits")
455 .flags(total
| nozero
| nonan
)
457 demandMshrHits
= SUM_DEMAND(mshr_hits
);
458 for (int i
= 0; i
< system
->maxMasters(); i
++) {
459 demandMshrHits
.subname(i
, system
->getMasterName(i
));
463 .name(name() + ".overall_mshr_hits")
464 .desc("number of overall MSHR hits")
465 .flags(total
| nozero
| nonan
)
467 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
468 for (int i
= 0; i
< system
->maxMasters(); i
++) {
469 overallMshrHits
.subname(i
, system
->getMasterName(i
));
472 // MSHR miss statistics
473 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
474 MemCmd
cmd(access_idx
);
475 const string
&cstr
= cmd
.toString();
477 mshr_misses
[access_idx
]
478 .init(system
->maxMasters())
479 .name(name() + "." + cstr
+ "_mshr_misses")
480 .desc("number of " + cstr
+ " MSHR misses")
481 .flags(total
| nozero
| nonan
)
483 for (int i
= 0; i
< system
->maxMasters(); i
++) {
484 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
489 .name(name() + ".demand_mshr_misses")
490 .desc("number of demand (read+write) MSHR misses")
491 .flags(total
| nozero
| nonan
)
493 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
494 for (int i
= 0; i
< system
->maxMasters(); i
++) {
495 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
499 .name(name() + ".overall_mshr_misses")
500 .desc("number of overall MSHR misses")
501 .flags(total
| nozero
| nonan
)
503 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
504 for (int i
= 0; i
< system
->maxMasters(); i
++) {
505 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
508 // MSHR miss latency statistics
509 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
510 MemCmd
cmd(access_idx
);
511 const string
&cstr
= cmd
.toString();
513 mshr_miss_latency
[access_idx
]
514 .init(system
->maxMasters())
515 .name(name() + "." + cstr
+ "_mshr_miss_latency")
516 .desc("number of " + cstr
+ " MSHR miss cycles")
517 .flags(total
| nozero
| nonan
)
519 for (int i
= 0; i
< system
->maxMasters(); i
++) {
520 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
524 demandMshrMissLatency
525 .name(name() + ".demand_mshr_miss_latency")
526 .desc("number of demand (read+write) MSHR miss cycles")
527 .flags(total
| nozero
| nonan
)
529 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
530 for (int i
= 0; i
< system
->maxMasters(); i
++) {
531 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
534 overallMshrMissLatency
535 .name(name() + ".overall_mshr_miss_latency")
536 .desc("number of overall MSHR miss cycles")
537 .flags(total
| nozero
| nonan
)
539 overallMshrMissLatency
=
540 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
541 for (int i
= 0; i
< system
->maxMasters(); i
++) {
542 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
545 // MSHR uncacheable statistics
546 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
547 MemCmd
cmd(access_idx
);
548 const string
&cstr
= cmd
.toString();
550 mshr_uncacheable
[access_idx
]
551 .init(system
->maxMasters())
552 .name(name() + "." + cstr
+ "_mshr_uncacheable")
553 .desc("number of " + cstr
+ " MSHR uncacheable")
554 .flags(total
| nozero
| nonan
)
556 for (int i
= 0; i
< system
->maxMasters(); i
++) {
557 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
561 overallMshrUncacheable
562 .name(name() + ".overall_mshr_uncacheable_misses")
563 .desc("number of overall MSHR uncacheable misses")
564 .flags(total
| nozero
| nonan
)
566 overallMshrUncacheable
=
567 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
568 for (int i
= 0; i
< system
->maxMasters(); i
++) {
569 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
572 // MSHR miss latency statistics
573 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
574 MemCmd
cmd(access_idx
);
575 const string
&cstr
= cmd
.toString();
577 mshr_uncacheable_lat
[access_idx
]
578 .init(system
->maxMasters())
579 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
580 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
581 .flags(total
| nozero
| nonan
)
583 for (int i
= 0; i
< system
->maxMasters(); i
++) {
584 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
588 overallMshrUncacheableLatency
589 .name(name() + ".overall_mshr_uncacheable_latency")
590 .desc("number of overall MSHR uncacheable cycles")
591 .flags(total
| nozero
| nonan
)
593 overallMshrUncacheableLatency
=
594 SUM_DEMAND(mshr_uncacheable_lat
) +
595 SUM_NON_DEMAND(mshr_uncacheable_lat
);
596 for (int i
= 0; i
< system
->maxMasters(); i
++) {
597 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
601 // MSHR access 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 mshrAccesses
[access_idx
]
607 .name(name() + "." + cstr
+ "_mshr_accesses")
608 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
609 .flags(total
| nozero
| nonan
)
611 mshrAccesses
[access_idx
] =
612 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
613 + mshr_uncacheable
[access_idx
];
617 .name(name() + ".demand_mshr_accesses")
618 .desc("number of demand (read+write) mshr accesses")
619 .flags(total
| nozero
| nonan
)
621 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
624 .name(name() + ".overall_mshr_accesses")
625 .desc("number of overall (read+write) mshr accesses")
626 .flags(total
| nozero
| nonan
)
628 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
629 + overallMshrUncacheable
;
632 // MSHR miss rate formulas
633 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
634 MemCmd
cmd(access_idx
);
635 const string
&cstr
= cmd
.toString();
637 mshrMissRate
[access_idx
]
638 .name(name() + "." + cstr
+ "_mshr_miss_rate")
639 .desc("mshr miss rate for " + cstr
+ " accesses")
640 .flags(total
| nozero
| nonan
)
642 mshrMissRate
[access_idx
] =
643 mshr_misses
[access_idx
] / accesses
[access_idx
];
645 for (int i
= 0; i
< system
->maxMasters(); i
++) {
646 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
651 .name(name() + ".demand_mshr_miss_rate")
652 .desc("mshr miss rate for demand accesses")
653 .flags(total
| nozero
| nonan
)
655 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
656 for (int i
= 0; i
< system
->maxMasters(); i
++) {
657 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
661 .name(name() + ".overall_mshr_miss_rate")
662 .desc("mshr miss rate for overall accesses")
663 .flags(total
| nozero
| nonan
)
665 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
666 for (int i
= 0; i
< system
->maxMasters(); i
++) {
667 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
670 // mshrMiss latency formulas
671 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
672 MemCmd
cmd(access_idx
);
673 const string
&cstr
= cmd
.toString();
675 avgMshrMissLatency
[access_idx
]
676 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
677 .desc("average " + cstr
+ " mshr miss latency")
678 .flags(total
| nozero
| nonan
)
680 avgMshrMissLatency
[access_idx
] =
681 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
683 for (int i
= 0; i
< system
->maxMasters(); i
++) {
684 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
688 demandAvgMshrMissLatency
689 .name(name() + ".demand_avg_mshr_miss_latency")
690 .desc("average overall mshr miss latency")
691 .flags(total
| nozero
| nonan
)
693 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
694 for (int i
= 0; i
< system
->maxMasters(); i
++) {
695 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
698 overallAvgMshrMissLatency
699 .name(name() + ".overall_avg_mshr_miss_latency")
700 .desc("average overall mshr miss latency")
701 .flags(total
| nozero
| nonan
)
703 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
704 for (int i
= 0; i
< system
->maxMasters(); i
++) {
705 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
708 // mshrUncacheable latency formulas
709 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
710 MemCmd
cmd(access_idx
);
711 const string
&cstr
= cmd
.toString();
713 avgMshrUncacheableLatency
[access_idx
]
714 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
715 .desc("average " + cstr
+ " mshr uncacheable latency")
716 .flags(total
| nozero
| nonan
)
718 avgMshrUncacheableLatency
[access_idx
] =
719 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
721 for (int i
= 0; i
< system
->maxMasters(); i
++) {
722 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
726 overallAvgMshrUncacheableLatency
727 .name(name() + ".overall_avg_mshr_uncacheable_latency")
728 .desc("average overall mshr uncacheable latency")
729 .flags(total
| nozero
| nonan
)
731 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
732 for (int i
= 0; i
< system
->maxMasters(); i
++) {
733 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
737 .init(system
->maxMasters())
738 .name(name() + ".mshr_cap_events")
739 .desc("number of times MSHR cap was activated")
740 .flags(total
| nozero
| nonan
)
742 for (int i
= 0; i
< system
->maxMasters(); i
++) {
743 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
746 //software prefetching stats
747 soft_prefetch_mshr_full
748 .init(system
->maxMasters())
749 .name(name() + ".soft_prefetch_mshr_full")
750 .desc("number of mshr full events for SW prefetching instrutions")
751 .flags(total
| nozero
| nonan
)
753 for (int i
= 0; i
< system
->maxMasters(); i
++) {
754 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
757 mshr_no_allocate_misses
758 .name(name() +".no_allocate_misses")
759 .desc("Number of misses that were no-allocate")
765 BaseCache::drain(DrainManager
*dm
)
767 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
768 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
772 setDrainState(Drainable::Draining
);
773 DPRINTF(Drain
, "Cache not drained\n");
777 setDrainState(Drainable::Drained
);
782 BaseCacheParams::create()
784 unsigned numSets
= size
/ (assoc
* system
->cacheLineSize());
788 if (dynamic_cast<FALRU
*>(tags
)) {
790 fatal("Got FALRU tags with more than one set\n");
791 return new Cache
<FALRU
>(this);
792 } else if (dynamic_cast<LRU
*>(tags
)) {
794 warn("Consider using FALRU tags for a fully associative cache\n");
795 return new Cache
<LRU
>(this);
796 } else if (dynamic_cast<RandomRepl
*>(tags
)) {
797 return new Cache
<RandomRepl
>(this);
799 fatal("No suitable tags selected\n");