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 "cpu/base.hh"
50 #include "debug/Cache.hh"
51 #include "debug/Drain.hh"
52 #include "mem/cache/tags/fa_lru.hh"
53 #include "mem/cache/tags/lru.hh"
54 #include "mem/cache/base.hh"
55 #include "mem/cache/cache.hh"
56 #include "mem/cache/mshr.hh"
57 #include "sim/full_system.hh"
61 BaseCache::CacheSlavePort::CacheSlavePort(const std::string
&_name
,
63 const std::string
&_label
)
64 : QueuedSlavePort(_name
, _cache
, queue
), queue(*_cache
, *this, _label
),
65 blocked(false), mustSendRetry(false), sendRetryEvent(this)
69 BaseCache::BaseCache(const Params
*p
)
71 mshrQueue("MSHRs", p
->mshrs
, 4, MSHRQueue_MSHRs
),
72 writeBuffer("write buffer", p
->write_buffers
, p
->mshrs
+1000,
73 MSHRQueue_WriteBuffer
),
74 blkSize(p
->block_size
),
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
),
82 missCount(p
->max_miss_count
),
83 addrRanges(p
->addr_ranges
.begin(), p
->addr_ranges
.end()),
89 BaseCache::CacheSlavePort::setBlocked()
92 DPRINTF(CachePort
, "Cache port %s blocking new requests\n", name());
94 // if we already scheduled a retry in this cycle, but it has not yet
95 // happened, cancel it
96 if (sendRetryEvent
.scheduled()) {
97 owner
.deschedule(sendRetryEvent
);
98 DPRINTF(CachePort
, "Cache port %s deschedule retry\n", name());
104 BaseCache::CacheSlavePort::clearBlocked()
107 DPRINTF(CachePort
, "Cache port %s accepting new requests\n", name());
110 DPRINTF(CachePort
, "Cache port %s sending retry\n", name());
111 mustSendRetry
= false;
112 // @TODO: need to find a better time (next bus cycle?)
113 owner
.schedule(sendRetryEvent
, curTick() + 1);
121 if (!cpuSidePort
->isConnected() || !memSidePort
->isConnected())
122 fatal("Cache ports on %s are not connected\n", name());
123 cpuSidePort
->sendRangeChange();
127 BaseCache::getMasterPort(const std::string
&if_name
, PortID idx
)
129 if (if_name
== "mem_side") {
132 return MemObject::getMasterPort(if_name
, idx
);
137 BaseCache::getSlavePort(const std::string
&if_name
, PortID idx
)
139 if (if_name
== "cpu_side") {
142 return MemObject::getSlavePort(if_name
, idx
);
147 BaseCache::regStats()
149 using namespace Stats
;
152 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
153 MemCmd
cmd(access_idx
);
154 const string
&cstr
= cmd
.toString();
157 .init(system
->maxMasters())
158 .name(name() + "." + cstr
+ "_hits")
159 .desc("number of " + cstr
+ " hits")
160 .flags(total
| nozero
| nonan
)
162 for (int i
= 0; i
< system
->maxMasters(); i
++) {
163 hits
[access_idx
].subname(i
, system
->getMasterName(i
));
167 // These macros make it easier to sum the right subset of commands and
168 // to change the subset of commands that are considered "demand" vs
170 #define SUM_DEMAND(s) \
171 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
173 // should writebacks be included here? prior code was inconsistent...
174 #define SUM_NON_DEMAND(s) \
175 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
178 .name(name() + ".demand_hits")
179 .desc("number of demand (read+write) hits")
180 .flags(total
| nozero
| nonan
)
182 demandHits
= SUM_DEMAND(hits
);
183 for (int i
= 0; i
< system
->maxMasters(); i
++) {
184 demandHits
.subname(i
, system
->getMasterName(i
));
188 .name(name() + ".overall_hits")
189 .desc("number of overall hits")
190 .flags(total
| nozero
| nonan
)
192 overallHits
= demandHits
+ SUM_NON_DEMAND(hits
);
193 for (int i
= 0; i
< system
->maxMasters(); i
++) {
194 overallHits
.subname(i
, system
->getMasterName(i
));
198 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
199 MemCmd
cmd(access_idx
);
200 const string
&cstr
= cmd
.toString();
203 .init(system
->maxMasters())
204 .name(name() + "." + cstr
+ "_misses")
205 .desc("number of " + cstr
+ " misses")
206 .flags(total
| nozero
| nonan
)
208 for (int i
= 0; i
< system
->maxMasters(); i
++) {
209 misses
[access_idx
].subname(i
, system
->getMasterName(i
));
214 .name(name() + ".demand_misses")
215 .desc("number of demand (read+write) misses")
216 .flags(total
| nozero
| nonan
)
218 demandMisses
= SUM_DEMAND(misses
);
219 for (int i
= 0; i
< system
->maxMasters(); i
++) {
220 demandMisses
.subname(i
, system
->getMasterName(i
));
224 .name(name() + ".overall_misses")
225 .desc("number of overall misses")
226 .flags(total
| nozero
| nonan
)
228 overallMisses
= demandMisses
+ SUM_NON_DEMAND(misses
);
229 for (int i
= 0; i
< system
->maxMasters(); i
++) {
230 overallMisses
.subname(i
, system
->getMasterName(i
));
233 // Miss latency statistics
234 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
235 MemCmd
cmd(access_idx
);
236 const string
&cstr
= cmd
.toString();
238 missLatency
[access_idx
]
239 .init(system
->maxMasters())
240 .name(name() + "." + cstr
+ "_miss_latency")
241 .desc("number of " + cstr
+ " miss cycles")
242 .flags(total
| nozero
| nonan
)
244 for (int i
= 0; i
< system
->maxMasters(); i
++) {
245 missLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
250 .name(name() + ".demand_miss_latency")
251 .desc("number of demand (read+write) miss cycles")
252 .flags(total
| nozero
| nonan
)
254 demandMissLatency
= SUM_DEMAND(missLatency
);
255 for (int i
= 0; i
< system
->maxMasters(); i
++) {
256 demandMissLatency
.subname(i
, system
->getMasterName(i
));
260 .name(name() + ".overall_miss_latency")
261 .desc("number of overall miss cycles")
262 .flags(total
| nozero
| nonan
)
264 overallMissLatency
= demandMissLatency
+ SUM_NON_DEMAND(missLatency
);
265 for (int i
= 0; i
< system
->maxMasters(); i
++) {
266 overallMissLatency
.subname(i
, system
->getMasterName(i
));
270 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
271 MemCmd
cmd(access_idx
);
272 const string
&cstr
= cmd
.toString();
275 .name(name() + "." + cstr
+ "_accesses")
276 .desc("number of " + cstr
+ " accesses(hits+misses)")
277 .flags(total
| nozero
| nonan
)
279 accesses
[access_idx
] = hits
[access_idx
] + misses
[access_idx
];
281 for (int i
= 0; i
< system
->maxMasters(); i
++) {
282 accesses
[access_idx
].subname(i
, system
->getMasterName(i
));
287 .name(name() + ".demand_accesses")
288 .desc("number of demand (read+write) accesses")
289 .flags(total
| nozero
| nonan
)
291 demandAccesses
= demandHits
+ demandMisses
;
292 for (int i
= 0; i
< system
->maxMasters(); i
++) {
293 demandAccesses
.subname(i
, system
->getMasterName(i
));
297 .name(name() + ".overall_accesses")
298 .desc("number of overall (read+write) accesses")
299 .flags(total
| nozero
| nonan
)
301 overallAccesses
= overallHits
+ overallMisses
;
302 for (int i
= 0; i
< system
->maxMasters(); i
++) {
303 overallAccesses
.subname(i
, system
->getMasterName(i
));
306 // miss rate formulas
307 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
308 MemCmd
cmd(access_idx
);
309 const string
&cstr
= cmd
.toString();
312 .name(name() + "." + cstr
+ "_miss_rate")
313 .desc("miss rate for " + cstr
+ " accesses")
314 .flags(total
| nozero
| nonan
)
316 missRate
[access_idx
] = misses
[access_idx
] / accesses
[access_idx
];
318 for (int i
= 0; i
< system
->maxMasters(); i
++) {
319 missRate
[access_idx
].subname(i
, system
->getMasterName(i
));
324 .name(name() + ".demand_miss_rate")
325 .desc("miss rate for demand accesses")
326 .flags(total
| nozero
| nonan
)
328 demandMissRate
= demandMisses
/ demandAccesses
;
329 for (int i
= 0; i
< system
->maxMasters(); i
++) {
330 demandMissRate
.subname(i
, system
->getMasterName(i
));
334 .name(name() + ".overall_miss_rate")
335 .desc("miss rate for overall accesses")
336 .flags(total
| nozero
| nonan
)
338 overallMissRate
= overallMisses
/ overallAccesses
;
339 for (int i
= 0; i
< system
->maxMasters(); i
++) {
340 overallMissRate
.subname(i
, system
->getMasterName(i
));
343 // miss latency formulas
344 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
345 MemCmd
cmd(access_idx
);
346 const string
&cstr
= cmd
.toString();
348 avgMissLatency
[access_idx
]
349 .name(name() + "." + cstr
+ "_avg_miss_latency")
350 .desc("average " + cstr
+ " miss latency")
351 .flags(total
| nozero
| nonan
)
353 avgMissLatency
[access_idx
] =
354 missLatency
[access_idx
] / misses
[access_idx
];
356 for (int i
= 0; i
< system
->maxMasters(); i
++) {
357 avgMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
362 .name(name() + ".demand_avg_miss_latency")
363 .desc("average overall miss latency")
364 .flags(total
| nozero
| nonan
)
366 demandAvgMissLatency
= demandMissLatency
/ demandMisses
;
367 for (int i
= 0; i
< system
->maxMasters(); i
++) {
368 demandAvgMissLatency
.subname(i
, system
->getMasterName(i
));
371 overallAvgMissLatency
372 .name(name() + ".overall_avg_miss_latency")
373 .desc("average overall miss latency")
374 .flags(total
| nozero
| nonan
)
376 overallAvgMissLatency
= overallMissLatency
/ overallMisses
;
377 for (int i
= 0; i
< system
->maxMasters(); i
++) {
378 overallAvgMissLatency
.subname(i
, system
->getMasterName(i
));
381 blocked_cycles
.init(NUM_BLOCKED_CAUSES
);
383 .name(name() + ".blocked_cycles")
384 .desc("number of cycles access was blocked")
385 .subname(Blocked_NoMSHRs
, "no_mshrs")
386 .subname(Blocked_NoTargets
, "no_targets")
390 blocked_causes
.init(NUM_BLOCKED_CAUSES
);
392 .name(name() + ".blocked")
393 .desc("number of cycles access was blocked")
394 .subname(Blocked_NoMSHRs
, "no_mshrs")
395 .subname(Blocked_NoTargets
, "no_targets")
399 .name(name() + ".avg_blocked_cycles")
400 .desc("average number of cycles each access was blocked")
401 .subname(Blocked_NoMSHRs
, "no_mshrs")
402 .subname(Blocked_NoTargets
, "no_targets")
405 avg_blocked
= blocked_cycles
/ blocked_causes
;
408 .name(name() + ".fast_writes")
409 .desc("number of fast writes performed")
413 .name(name() + ".cache_copies")
414 .desc("number of cache copies performed")
418 .init(system
->maxMasters())
419 .name(name() + ".writebacks")
420 .desc("number of writebacks")
421 .flags(total
| nozero
| nonan
)
423 for (int i
= 0; i
< system
->maxMasters(); i
++) {
424 writebacks
.subname(i
, system
->getMasterName(i
));
428 // MSHR hit statistics
429 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
430 MemCmd
cmd(access_idx
);
431 const string
&cstr
= cmd
.toString();
433 mshr_hits
[access_idx
]
434 .init(system
->maxMasters())
435 .name(name() + "." + cstr
+ "_mshr_hits")
436 .desc("number of " + cstr
+ " MSHR hits")
437 .flags(total
| nozero
| nonan
)
439 for (int i
= 0; i
< system
->maxMasters(); i
++) {
440 mshr_hits
[access_idx
].subname(i
, system
->getMasterName(i
));
445 .name(name() + ".demand_mshr_hits")
446 .desc("number of demand (read+write) MSHR hits")
447 .flags(total
| nozero
| nonan
)
449 demandMshrHits
= SUM_DEMAND(mshr_hits
);
450 for (int i
= 0; i
< system
->maxMasters(); i
++) {
451 demandMshrHits
.subname(i
, system
->getMasterName(i
));
455 .name(name() + ".overall_mshr_hits")
456 .desc("number of overall MSHR hits")
457 .flags(total
| nozero
| nonan
)
459 overallMshrHits
= demandMshrHits
+ SUM_NON_DEMAND(mshr_hits
);
460 for (int i
= 0; i
< system
->maxMasters(); i
++) {
461 overallMshrHits
.subname(i
, system
->getMasterName(i
));
464 // MSHR miss statistics
465 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
466 MemCmd
cmd(access_idx
);
467 const string
&cstr
= cmd
.toString();
469 mshr_misses
[access_idx
]
470 .init(system
->maxMasters())
471 .name(name() + "." + cstr
+ "_mshr_misses")
472 .desc("number of " + cstr
+ " MSHR misses")
473 .flags(total
| nozero
| nonan
)
475 for (int i
= 0; i
< system
->maxMasters(); i
++) {
476 mshr_misses
[access_idx
].subname(i
, system
->getMasterName(i
));
481 .name(name() + ".demand_mshr_misses")
482 .desc("number of demand (read+write) MSHR misses")
483 .flags(total
| nozero
| nonan
)
485 demandMshrMisses
= SUM_DEMAND(mshr_misses
);
486 for (int i
= 0; i
< system
->maxMasters(); i
++) {
487 demandMshrMisses
.subname(i
, system
->getMasterName(i
));
491 .name(name() + ".overall_mshr_misses")
492 .desc("number of overall MSHR misses")
493 .flags(total
| nozero
| nonan
)
495 overallMshrMisses
= demandMshrMisses
+ SUM_NON_DEMAND(mshr_misses
);
496 for (int i
= 0; i
< system
->maxMasters(); i
++) {
497 overallMshrMisses
.subname(i
, system
->getMasterName(i
));
500 // MSHR miss latency statistics
501 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
502 MemCmd
cmd(access_idx
);
503 const string
&cstr
= cmd
.toString();
505 mshr_miss_latency
[access_idx
]
506 .init(system
->maxMasters())
507 .name(name() + "." + cstr
+ "_mshr_miss_latency")
508 .desc("number of " + cstr
+ " MSHR miss cycles")
509 .flags(total
| nozero
| nonan
)
511 for (int i
= 0; i
< system
->maxMasters(); i
++) {
512 mshr_miss_latency
[access_idx
].subname(i
, system
->getMasterName(i
));
516 demandMshrMissLatency
517 .name(name() + ".demand_mshr_miss_latency")
518 .desc("number of demand (read+write) MSHR miss cycles")
519 .flags(total
| nozero
| nonan
)
521 demandMshrMissLatency
= SUM_DEMAND(mshr_miss_latency
);
522 for (int i
= 0; i
< system
->maxMasters(); i
++) {
523 demandMshrMissLatency
.subname(i
, system
->getMasterName(i
));
526 overallMshrMissLatency
527 .name(name() + ".overall_mshr_miss_latency")
528 .desc("number of overall MSHR miss cycles")
529 .flags(total
| nozero
| nonan
)
531 overallMshrMissLatency
=
532 demandMshrMissLatency
+ SUM_NON_DEMAND(mshr_miss_latency
);
533 for (int i
= 0; i
< system
->maxMasters(); i
++) {
534 overallMshrMissLatency
.subname(i
, system
->getMasterName(i
));
537 // MSHR uncacheable statistics
538 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
539 MemCmd
cmd(access_idx
);
540 const string
&cstr
= cmd
.toString();
542 mshr_uncacheable
[access_idx
]
543 .init(system
->maxMasters())
544 .name(name() + "." + cstr
+ "_mshr_uncacheable")
545 .desc("number of " + cstr
+ " MSHR uncacheable")
546 .flags(total
| nozero
| nonan
)
548 for (int i
= 0; i
< system
->maxMasters(); i
++) {
549 mshr_uncacheable
[access_idx
].subname(i
, system
->getMasterName(i
));
553 overallMshrUncacheable
554 .name(name() + ".overall_mshr_uncacheable_misses")
555 .desc("number of overall MSHR uncacheable misses")
556 .flags(total
| nozero
| nonan
)
558 overallMshrUncacheable
=
559 SUM_DEMAND(mshr_uncacheable
) + SUM_NON_DEMAND(mshr_uncacheable
);
560 for (int i
= 0; i
< system
->maxMasters(); i
++) {
561 overallMshrUncacheable
.subname(i
, system
->getMasterName(i
));
564 // MSHR miss latency statistics
565 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
566 MemCmd
cmd(access_idx
);
567 const string
&cstr
= cmd
.toString();
569 mshr_uncacheable_lat
[access_idx
]
570 .init(system
->maxMasters())
571 .name(name() + "." + cstr
+ "_mshr_uncacheable_latency")
572 .desc("number of " + cstr
+ " MSHR uncacheable cycles")
573 .flags(total
| nozero
| nonan
)
575 for (int i
= 0; i
< system
->maxMasters(); i
++) {
576 mshr_uncacheable_lat
[access_idx
].subname(i
, system
->getMasterName(i
));
580 overallMshrUncacheableLatency
581 .name(name() + ".overall_mshr_uncacheable_latency")
582 .desc("number of overall MSHR uncacheable cycles")
583 .flags(total
| nozero
| nonan
)
585 overallMshrUncacheableLatency
=
586 SUM_DEMAND(mshr_uncacheable_lat
) +
587 SUM_NON_DEMAND(mshr_uncacheable_lat
);
588 for (int i
= 0; i
< system
->maxMasters(); i
++) {
589 overallMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
593 // MSHR access formulas
594 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
595 MemCmd
cmd(access_idx
);
596 const string
&cstr
= cmd
.toString();
598 mshrAccesses
[access_idx
]
599 .name(name() + "." + cstr
+ "_mshr_accesses")
600 .desc("number of " + cstr
+ " mshr accesses(hits+misses)")
601 .flags(total
| nozero
| nonan
)
603 mshrAccesses
[access_idx
] =
604 mshr_hits
[access_idx
] + mshr_misses
[access_idx
]
605 + mshr_uncacheable
[access_idx
];
609 .name(name() + ".demand_mshr_accesses")
610 .desc("number of demand (read+write) mshr accesses")
611 .flags(total
| nozero
| nonan
)
613 demandMshrAccesses
= demandMshrHits
+ demandMshrMisses
;
616 .name(name() + ".overall_mshr_accesses")
617 .desc("number of overall (read+write) mshr accesses")
618 .flags(total
| nozero
| nonan
)
620 overallMshrAccesses
= overallMshrHits
+ overallMshrMisses
621 + overallMshrUncacheable
;
624 // MSHR miss rate formulas
625 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
626 MemCmd
cmd(access_idx
);
627 const string
&cstr
= cmd
.toString();
629 mshrMissRate
[access_idx
]
630 .name(name() + "." + cstr
+ "_mshr_miss_rate")
631 .desc("mshr miss rate for " + cstr
+ " accesses")
632 .flags(total
| nozero
| nonan
)
634 mshrMissRate
[access_idx
] =
635 mshr_misses
[access_idx
] / accesses
[access_idx
];
637 for (int i
= 0; i
< system
->maxMasters(); i
++) {
638 mshrMissRate
[access_idx
].subname(i
, system
->getMasterName(i
));
643 .name(name() + ".demand_mshr_miss_rate")
644 .desc("mshr miss rate for demand accesses")
645 .flags(total
| nozero
| nonan
)
647 demandMshrMissRate
= demandMshrMisses
/ demandAccesses
;
648 for (int i
= 0; i
< system
->maxMasters(); i
++) {
649 demandMshrMissRate
.subname(i
, system
->getMasterName(i
));
653 .name(name() + ".overall_mshr_miss_rate")
654 .desc("mshr miss rate for overall accesses")
655 .flags(total
| nozero
| nonan
)
657 overallMshrMissRate
= overallMshrMisses
/ overallAccesses
;
658 for (int i
= 0; i
< system
->maxMasters(); i
++) {
659 overallMshrMissRate
.subname(i
, system
->getMasterName(i
));
662 // mshrMiss latency formulas
663 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
664 MemCmd
cmd(access_idx
);
665 const string
&cstr
= cmd
.toString();
667 avgMshrMissLatency
[access_idx
]
668 .name(name() + "." + cstr
+ "_avg_mshr_miss_latency")
669 .desc("average " + cstr
+ " mshr miss latency")
670 .flags(total
| nozero
| nonan
)
672 avgMshrMissLatency
[access_idx
] =
673 mshr_miss_latency
[access_idx
] / mshr_misses
[access_idx
];
675 for (int i
= 0; i
< system
->maxMasters(); i
++) {
676 avgMshrMissLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
680 demandAvgMshrMissLatency
681 .name(name() + ".demand_avg_mshr_miss_latency")
682 .desc("average overall mshr miss latency")
683 .flags(total
| nozero
| nonan
)
685 demandAvgMshrMissLatency
= demandMshrMissLatency
/ demandMshrMisses
;
686 for (int i
= 0; i
< system
->maxMasters(); i
++) {
687 demandAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
690 overallAvgMshrMissLatency
691 .name(name() + ".overall_avg_mshr_miss_latency")
692 .desc("average overall mshr miss latency")
693 .flags(total
| nozero
| nonan
)
695 overallAvgMshrMissLatency
= overallMshrMissLatency
/ overallMshrMisses
;
696 for (int i
= 0; i
< system
->maxMasters(); i
++) {
697 overallAvgMshrMissLatency
.subname(i
, system
->getMasterName(i
));
700 // mshrUncacheable latency formulas
701 for (int access_idx
= 0; access_idx
< MemCmd::NUM_MEM_CMDS
; ++access_idx
) {
702 MemCmd
cmd(access_idx
);
703 const string
&cstr
= cmd
.toString();
705 avgMshrUncacheableLatency
[access_idx
]
706 .name(name() + "." + cstr
+ "_avg_mshr_uncacheable_latency")
707 .desc("average " + cstr
+ " mshr uncacheable latency")
708 .flags(total
| nozero
| nonan
)
710 avgMshrUncacheableLatency
[access_idx
] =
711 mshr_uncacheable_lat
[access_idx
] / mshr_uncacheable
[access_idx
];
713 for (int i
= 0; i
< system
->maxMasters(); i
++) {
714 avgMshrUncacheableLatency
[access_idx
].subname(i
, system
->getMasterName(i
));
718 overallAvgMshrUncacheableLatency
719 .name(name() + ".overall_avg_mshr_uncacheable_latency")
720 .desc("average overall mshr uncacheable latency")
721 .flags(total
| nozero
| nonan
)
723 overallAvgMshrUncacheableLatency
= overallMshrUncacheableLatency
/ overallMshrUncacheable
;
724 for (int i
= 0; i
< system
->maxMasters(); i
++) {
725 overallAvgMshrUncacheableLatency
.subname(i
, system
->getMasterName(i
));
729 .init(system
->maxMasters())
730 .name(name() + ".mshr_cap_events")
731 .desc("number of times MSHR cap was activated")
732 .flags(total
| nozero
| nonan
)
734 for (int i
= 0; i
< system
->maxMasters(); i
++) {
735 mshr_cap_events
.subname(i
, system
->getMasterName(i
));
738 //software prefetching stats
739 soft_prefetch_mshr_full
740 .init(system
->maxMasters())
741 .name(name() + ".soft_prefetch_mshr_full")
742 .desc("number of mshr full events for SW prefetching instrutions")
743 .flags(total
| nozero
| nonan
)
745 for (int i
= 0; i
< system
->maxMasters(); i
++) {
746 soft_prefetch_mshr_full
.subname(i
, system
->getMasterName(i
));
749 mshr_no_allocate_misses
750 .name(name() +".no_allocate_misses")
751 .desc("Number of misses that were no-allocate")
757 BaseCache::drain(DrainManager
*dm
)
759 int count
= memSidePort
->drain(dm
) + cpuSidePort
->drain(dm
) +
760 mshrQueue
.drain(dm
) + writeBuffer
.drain(dm
);
764 setDrainState(Drainable::Draining
);
765 DPRINTF(Drain
, "Cache not drained\n");
769 setDrainState(Drainable::Drained
);
774 BaseCacheParams::create()
776 int numSets
= size
/ (assoc
* block_size
);
779 FALRU
*tags
= new FALRU(block_size
, size
, hit_latency
);
780 return new Cache
<FALRU
>(this, tags
);
782 LRU
*tags
= new LRU(numSets
, block_size
, assoc
, hit_latency
);
783 return new Cache
<LRU
>(this, tags
);