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::regStats()
159 using namespace Stats
;
162 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
163 MemCmd
cmd(access_idx
);
164 const string
&cstr
= cmd
.toString();
167 .init(system
->maxMasters())
168 .name(name() + "." + cstr
+ "_hits")
169 .desc("number of " + cstr
+ " hits")
170 .flags(total
| nozero
| nonan
)
172 for (int i
= 0; i
< system
->maxMasters(); i
++) {
173 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
177 // These macros make it easier to sum the right subset of commands and
178 // to change the subset of commands that are considered "demand" vs
180 #define SUM_DEMAND(s) \
181 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
183 // should writebacks be included here? prior code was inconsistent...
184 #define SUM_NON_DEMAND(s) \
185 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
188 .name(name() + ".demand_hits")
189 .desc("number of demand (read+write) hits")
190 .flags(total
| nozero
| nonan
)
192 demandHits
= SUM_DEMAND(hits
);
193 for (int i
= 0; i
< system
->maxMasters(); i
++) {
194 demandHits
.subname(i
, system
->getMasterName(i
));
198 .name(name() + ".overall_hits")
199 .desc("number of overall hits")
200 .flags(total
| nozero
| nonan
)
202 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
203 for (int i
= 0; i
< system
->maxMasters(); i
++) {
204 overallHits
.subname(i
, system
->getMasterName(i
));
208 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
209 MemCmd
cmd(access_idx
);
210 const string
&cstr
= cmd
.toString();
213 .init(system
->maxMasters())
214 .name(name() + "." + cstr
+ "_misses")
215 .desc("number of " + cstr
+ " misses")
216 .flags(total
| nozero
| nonan
)
218 for (int i
= 0; i
< system
->maxMasters(); i
++) {
219 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
224 .name(name() + ".demand_misses")
225 .desc("number of demand (read+write) misses")
226 .flags(total
| nozero
| nonan
)
228 demandMisses
= SUM_DEMAND(misses
);
229 for (int i
= 0; i
< system
->maxMasters(); i
++) {
230 demandMisses
.subname(i
, system
->getMasterName(i
));
234 .name(name() + ".overall_misses")
235 .desc("number of overall misses")
236 .flags(total
| nozero
| nonan
)
238 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
239 for (int i
= 0; i
< system
->maxMasters(); i
++) {
240 overallMisses
.subname(i
, system
->getMasterName(i
));
243 // Miss latency statistics
244 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
245 MemCmd
cmd(access_idx
);
246 const string
&cstr
= cmd
.toString();
248 missLatency
[access_idx
]
249 .init(system
->maxMasters())
250 .name(name() + "." + cstr
+ "_miss_latency")
251 .desc("number of " + cstr
+ " miss cycles")
252 .flags(total
| nozero
| nonan
)
254 for (int i
= 0; i
< system
->maxMasters(); i
++) {
255 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
260 .name(name() + ".demand_miss_latency")
261 .desc("number of demand (read+write) miss cycles")
262 .flags(total
| nozero
| nonan
)
264 demandMissLatency
= SUM_DEMAND(missLatency
);
265 for (int i
= 0; i
< system
->maxMasters(); i
++) {
266 demandMissLatency
.subname(i
, system
->getMasterName(i
));
270 .name(name() + ".overall_miss_latency")
271 .desc("number of overall miss cycles")
272 .flags(total
| nozero
| nonan
)
274 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
275 for (int i
= 0; i
< system
->maxMasters(); i
++) {
276 overallMissLatency
.subname(i
, system
->getMasterName(i
));
280 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
281 MemCmd
cmd(access_idx
);
282 const string
&cstr
= cmd
.toString();
285 .name(name() + "." + cstr
+ "_accesses")
286 .desc("number of " + cstr
+ " accesses(hits+misses)")
287 .flags(total
| nozero
| nonan
)
289 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
291 for (int i
= 0; i
< system
->maxMasters(); i
++) {
292 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
297 .name(name() + ".demand_accesses")
298 .desc("number of demand (read+write) accesses")
299 .flags(total
| nozero
| nonan
)
301 demandAccesses
= demandHits
+ demandMisses
;
302 for (int i
= 0; i
< system
->maxMasters(); i
++) {
303 demandAccesses
.subname(i
, system
->getMasterName(i
));
307 .name(name() + ".overall_accesses")
308 .desc("number of overall (read+write) accesses")
309 .flags(total
| nozero
| nonan
)
311 overallAccesses
= overallHits
+ overallMisses
;
312 for (int i
= 0; i
< system
->maxMasters(); i
++) {
313 overallAccesses
.subname(i
, system
->getMasterName(i
));
316 // miss rate formulas
317 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
318 MemCmd
cmd(access_idx
);
319 const string
&cstr
= cmd
.toString();
322 .name(name() + "." + cstr
+ "_miss_rate")
323 .desc("miss rate for " + cstr
+ " accesses")
324 .flags(total
| nozero
| nonan
)
326 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
328 for (int i
= 0; i
< system
->maxMasters(); i
++) {
329 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
334 .name(name() + ".demand_miss_rate")
335 .desc("miss rate for demand accesses")
336 .flags(total
| nozero
| nonan
)
338 demandMissRate
= demandMisses
/ demandAccesses
;
339 for (int i
= 0; i
< system
->maxMasters(); i
++) {
340 demandMissRate
.subname(i
, system
->getMasterName(i
));
344 .name(name() + ".overall_miss_rate")
345 .desc("miss rate for overall accesses")
346 .flags(total
| nozero
| nonan
)
348 overallMissRate
= overallMisses
/ overallAccesses
;
349 for (int i
= 0; i
< system
->maxMasters(); i
++) {
350 overallMissRate
.subname(i
, system
->getMasterName(i
));
353 // miss latency formulas
354 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
355 MemCmd
cmd(access_idx
);
356 const string
&cstr
= cmd
.toString();
358 avgMissLatency
[access_idx
]
359 .name(name() + "." + cstr
+ "_avg_miss_latency")
360 .desc("average " + cstr
+ " miss latency")
361 .flags(total
| nozero
| nonan
)
363 avgMissLatency
[access_idx
] =
364 missLatency
[access_idx
] / misses
[access_idx
];
366 for (int i
= 0; i
< system
->maxMasters(); i
++) {
367 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
372 .name(name() + ".demand_avg_miss_latency")
373 .desc("average overall miss latency")
374 .flags(total
| nozero
| nonan
)
376 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
377 for (int i
= 0; i
< system
->maxMasters(); i
++) {
378 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
381 overallAvgMissLatency
382 .name(name() + ".overall_avg_miss_latency")
383 .desc("average overall miss latency")
384 .flags(total
| nozero
| nonan
)
386 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
387 for (int i
= 0; i
< system
->maxMasters(); i
++) {
388 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
391 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
393 .name(name() + ".blocked_cycles")
394 .desc("number of cycles access was blocked")
395 .subname(Blocked_NoMSHRs
, "no_mshrs")
396 .subname(Blocked_NoTargets
, "no_targets")
400 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
402 .name(name() + ".blocked")
403 .desc("number of cycles access was blocked")
404 .subname(Blocked_NoMSHRs
, "no_mshrs")
405 .subname(Blocked_NoTargets
, "no_targets")
409 .name(name() + ".avg_blocked_cycles")
410 .desc("average number of cycles each access was blocked")
411 .subname(Blocked_NoMSHRs
, "no_mshrs")
412 .subname(Blocked_NoTargets
, "no_targets")
415 avg_blocked
= blocked_cycles
/ blocked_causes
;
418 .name(name() + ".fast_writes")
419 .desc("number of fast writes performed")
423 .name(name() + ".cache_copies")
424 .desc("number of cache copies performed")
428 .init(system
->maxMasters())
429 .name(name() + ".writebacks")
430 .desc("number of writebacks")
431 .flags(total
| nozero
| nonan
)
433 for (int i
= 0; i
< system
->maxMasters(); i
++) {
434 writebacks
.subname(i
, system
->getMasterName(i
));
438 // MSHR hit statistics
439 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
440 MemCmd
cmd(access_idx
);
441 const string
&cstr
= cmd
.toString();
443 mshr_hits
[access_idx
]
444 .init(system
->maxMasters())
445 .name(name() + "." + cstr
+ "_mshr_hits")
446 .desc("number of " + cstr
+ " MSHR hits")
447 .flags(total
| nozero
| nonan
)
449 for (int i
= 0; i
< system
->maxMasters(); i
++) {
450 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
455 .name(name() + ".demand_mshr_hits")
456 .desc("number of demand (read+write) MSHR hits")
457 .flags(total
| nozero
| nonan
)
459 demandMshrHits
= SUM_DEMAND(mshr_hits
);
460 for (int i
= 0; i
< system
->maxMasters(); i
++) {
461 demandMshrHits
.subname(i
, system
->getMasterName(i
));
465 .name(name() + ".overall_mshr_hits")
466 .desc("number of overall MSHR hits")
467 .flags(total
| nozero
| nonan
)
469 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
470 for (int i
= 0; i
< system
->maxMasters(); i
++) {
471 overallMshrHits
.subname(i
, system
->getMasterName(i
));
474 // MSHR miss statistics
475 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
476 MemCmd
cmd(access_idx
);
477 const string
&cstr
= cmd
.toString();
479 mshr_misses
[access_idx
]
480 .init(system
->maxMasters())
481 .name(name() + "." + cstr
+ "_mshr_misses")
482 .desc("number of " + cstr
+ " MSHR misses")
483 .flags(total
| nozero
| nonan
)
485 for (int i
= 0; i
< system
->maxMasters(); i
++) {
486 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
491 .name(name() + ".demand_mshr_misses")
492 .desc("number of demand (read+write) MSHR misses")
493 .flags(total
| nozero
| nonan
)
495 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
496 for (int i
= 0; i
< system
->maxMasters(); i
++) {
497 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
501 .name(name() + ".overall_mshr_misses")
502 .desc("number of overall MSHR misses")
503 .flags(total
| nozero
| nonan
)
505 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
506 for (int i
= 0; i
< system
->maxMasters(); i
++) {
507 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
510 // MSHR miss latency statistics
511 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
512 MemCmd
cmd(access_idx
);
513 const string
&cstr
= cmd
.toString();
515 mshr_miss_latency
[access_idx
]
516 .init(system
->maxMasters())
517 .name(name() + "." + cstr
+ "_mshr_miss_latency")
518 .desc("number of " + cstr
+ " MSHR miss cycles")
519 .flags(total
| nozero
| nonan
)
521 for (int i
= 0; i
< system
->maxMasters(); i
++) {
522 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
526 demandMshrMissLatency
527 .name(name() + ".demand_mshr_miss_latency")
528 .desc("number of demand (read+write) MSHR miss cycles")
529 .flags(total
| nozero
| nonan
)
531 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
532 for (int i
= 0; i
< system
->maxMasters(); i
++) {
533 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
536 overallMshrMissLatency
537 .name(name() + ".overall_mshr_miss_latency")
538 .desc("number of overall MSHR miss cycles")
539 .flags(total
| nozero
| nonan
)
541 overallMshrMissLatency
=
542 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
543 for (int i
= 0; i
< system
->maxMasters(); i
++) {
544 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
547 // MSHR uncacheable statistics
548 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
549 MemCmd
cmd(access_idx
);
550 const string
&cstr
= cmd
.toString();
552 mshr_uncacheable
[access_idx
]
553 .init(system
->maxMasters())
554 .name(name() + "." + cstr
+ "_mshr_uncacheable")
555 .desc("number of " + cstr
+ " MSHR uncacheable")
556 .flags(total
| nozero
| nonan
)
558 for (int i
= 0; i
< system
->maxMasters(); i
++) {
559 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
563 overallMshrUncacheable
564 .name(name() + ".overall_mshr_uncacheable_misses")
565 .desc("number of overall MSHR uncacheable misses")
566 .flags(total
| nozero
| nonan
)
568 overallMshrUncacheable
=
569 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
570 for (int i
= 0; i
< system
->maxMasters(); i
++) {
571 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
574 // MSHR miss latency statistics
575 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
576 MemCmd
cmd(access_idx
);
577 const string
&cstr
= cmd
.toString();
579 mshr_uncacheable_lat
[access_idx
]
580 .init(system
->maxMasters())
581 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
582 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
583 .flags(total
| nozero
| nonan
)
585 for (int i
= 0; i
< system
->maxMasters(); i
++) {
586 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
590 overallMshrUncacheableLatency
591 .name(name() + ".overall_mshr_uncacheable_latency")
592 .desc("number of overall MSHR uncacheable cycles")
593 .flags(total
| nozero
| nonan
)
595 overallMshrUncacheableLatency
=
596 SUM_DEMAND(mshr_uncacheable_lat
) +
597 SUM_NON_DEMAND(mshr_uncacheable_lat
);
598 for (int i
= 0; i
< system
->maxMasters(); i
++) {
599 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
603 // MSHR access formulas
604 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
605 MemCmd
cmd(access_idx
);
606 const string
&cstr
= cmd
.toString();
608 mshrAccesses
[access_idx
]
609 .name(name() + "." + cstr
+ "_mshr_accesses")
610 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
611 .flags(total
| nozero
| nonan
)
613 mshrAccesses
[access_idx
] =
614 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
615 + mshr_uncacheable
[access_idx
];
619 .name(name() + ".demand_mshr_accesses")
620 .desc("number of demand (read+write) mshr accesses")
621 .flags(total
| nozero
| nonan
)
623 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
626 .name(name() + ".overall_mshr_accesses")
627 .desc("number of overall (read+write) mshr accesses")
628 .flags(total
| nozero
| nonan
)
630 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
631 + overallMshrUncacheable
;
634 // MSHR miss rate formulas
635 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
636 MemCmd
cmd(access_idx
);
637 const string
&cstr
= cmd
.toString();
639 mshrMissRate
[access_idx
]
640 .name(name() + "." + cstr
+ "_mshr_miss_rate")
641 .desc("mshr miss rate for " + cstr
+ " accesses")
642 .flags(total
| nozero
| nonan
)
644 mshrMissRate
[access_idx
] =
645 mshr_misses
[access_idx
] / accesses
[access_idx
];
647 for (int i
= 0; i
< system
->maxMasters(); i
++) {
648 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
653 .name(name() + ".demand_mshr_miss_rate")
654 .desc("mshr miss rate for demand accesses")
655 .flags(total
| nozero
| nonan
)
657 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
658 for (int i
= 0; i
< system
->maxMasters(); i
++) {
659 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
663 .name(name() + ".overall_mshr_miss_rate")
664 .desc("mshr miss rate for overall accesses")
665 .flags(total
| nozero
| nonan
)
667 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
668 for (int i
= 0; i
< system
->maxMasters(); i
++) {
669 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
672 // mshrMiss latency formulas
673 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
674 MemCmd
cmd(access_idx
);
675 const string
&cstr
= cmd
.toString();
677 avgMshrMissLatency
[access_idx
]
678 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
679 .desc("average " + cstr
+ " mshr miss latency")
680 .flags(total
| nozero
| nonan
)
682 avgMshrMissLatency
[access_idx
] =
683 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
685 for (int i
= 0; i
< system
->maxMasters(); i
++) {
686 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
690 demandAvgMshrMissLatency
691 .name(name() + ".demand_avg_mshr_miss_latency")
692 .desc("average overall mshr miss latency")
693 .flags(total
| nozero
| nonan
)
695 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
696 for (int i
= 0; i
< system
->maxMasters(); i
++) {
697 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
700 overallAvgMshrMissLatency
701 .name(name() + ".overall_avg_mshr_miss_latency")
702 .desc("average overall mshr miss latency")
703 .flags(total
| nozero
| nonan
)
705 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
706 for (int i
= 0; i
< system
->maxMasters(); i
++) {
707 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
710 // mshrUncacheable latency formulas
711 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
712 MemCmd
cmd(access_idx
);
713 const string
&cstr
= cmd
.toString();
715 avgMshrUncacheableLatency
[access_idx
]
716 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
717 .desc("average " + cstr
+ " mshr uncacheable latency")
718 .flags(total
| nozero
| nonan
)
720 avgMshrUncacheableLatency
[access_idx
] =
721 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
723 for (int i
= 0; i
< system
->maxMasters(); i
++) {
724 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
728 overallAvgMshrUncacheableLatency
729 .name(name() + ".overall_avg_mshr_uncacheable_latency")
730 .desc("average overall mshr uncacheable latency")
731 .flags(total
| nozero
| nonan
)
733 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
734 for (int i
= 0; i
< system
->maxMasters(); i
++) {
735 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
739 .init(system
->maxMasters())
740 .name(name() + ".mshr_cap_events")
741 .desc("number of times MSHR cap was activated")
742 .flags(total
| nozero
| nonan
)
744 for (int i
= 0; i
< system
->maxMasters(); i
++) {
745 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
748 //software prefetching stats
749 soft_prefetch_mshr_full
750 .init(system
->maxMasters())
751 .name(name() + ".soft_prefetch_mshr_full")
752 .desc("number of mshr full events for SW prefetching instrutions")
753 .flags(total
| nozero
| nonan
)
755 for (int i
= 0; i
< system
->maxMasters(); i
++) {
756 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
759 mshr_no_allocate_misses
760 .name(name() +".no_allocate_misses")
761 .desc("Number of misses that were no-allocate")
767 BaseCache::drain(DrainManager
*dm
)
769 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
770 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
774 setDrainState(Drainable::Draining
);
775 DPRINTF(Drain
, "Cache not drained\n");
779 setDrainState(Drainable::Drained
);
784 BaseCacheParams::create()
786 unsigned numSets
= size
/ (assoc
* system
->cacheLineSize());
790 if (dynamic_cast<FALRU
*>(tags
)) {
792 fatal("Got FALRU tags with more than one set\n");
793 return new Cache
<FALRU
>(this);
794 } else if (dynamic_cast<LRU
*>(tags
)) {
796 warn("Consider using FALRU tags for a fully associative cache\n");
797 return new Cache
<LRU
>(this);
798 } else if (dynamic_cast<RandomRepl
*>(tags
)) {
799 return new Cache
<RandomRepl
>(this);
801 fatal("No suitable tags selected\n");