sim: Make the drain state a global typed enum
[gem5.git] / src / mem / cache / base.cc
1 /*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved.
4 *
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.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
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.
27 *
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.
39 *
40 * Authors: Erik Hallnor
41 */
42
43 /**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
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"
57
58 using namespace std;
59
60 BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
61 BaseCache *_cache,
62 const std::string &_label)
63 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
64 blocked(false), mustSendRetry(false), sendRetryEvent(this)
65 {
66 }
67
68 BaseCache::BaseCache(const Params *p)
69 : MemObject(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 isReadOnly(p->is_read_only),
82 blocked(0),
83 order(0),
84 noTargetMSHR(NULL),
85 missCount(p->max_miss_count),
86 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
87 system(p->system)
88 {
89 }
90
91 void
92 BaseCache::CacheSlavePort::setBlocked()
93 {
94 assert(!blocked);
95 DPRINTF(CachePort, "Port is blocking new requests\n");
96 blocked = true;
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;
103 }
104 }
105
106 void
107 BaseCache::CacheSlavePort::clearBlocked()
108 {
109 assert(blocked);
110 DPRINTF(CachePort, "Port is accepting new requests\n");
111 blocked = false;
112 if (mustSendRetry) {
113 // @TODO: need to find a better time (next cycle?)
114 owner.schedule(sendRetryEvent, curTick() + 1);
115 }
116 }
117
118 void
119 BaseCache::CacheSlavePort::processSendRetry()
120 {
121 DPRINTF(CachePort, "Port is sending retry\n");
122
123 // reset the flag and call retry
124 mustSendRetry = false;
125 sendRetryReq();
126 }
127
128 void
129 BaseCache::init()
130 {
131 if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
132 fatal("Cache ports on %s are not connected\n", name());
133 cpuSidePort->sendRangeChange();
134 }
135
136 BaseMasterPort &
137 BaseCache::getMasterPort(const std::string &if_name, PortID idx)
138 {
139 if (if_name == "mem_side") {
140 return *memSidePort;
141 } else {
142 return MemObject::getMasterPort(if_name, idx);
143 }
144 }
145
146 BaseSlavePort &
147 BaseCache::getSlavePort(const std::string &if_name, PortID idx)
148 {
149 if (if_name == "cpu_side") {
150 return *cpuSidePort;
151 } else {
152 return MemObject::getSlavePort(if_name, idx);
153 }
154 }
155
156 bool
157 BaseCache::inRange(Addr addr) const
158 {
159 for (const auto& r : addrRanges) {
160 if (r.contains(addr)) {
161 return true;
162 }
163 }
164 return false;
165 }
166
167 void
168 BaseCache::regStats()
169 {
170 using namespace Stats;
171
172 // Hit statistics
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();
176
177 hits[access_idx]
178 .init(system->maxMasters())
179 .name(name() + "." + cstr + "_hits")
180 .desc("number of " + cstr + " hits")
181 .flags(total | nozero | nonan)
182 ;
183 for (int i = 0; i < system->maxMasters(); i++) {
184 hits[access_idx].subname(i, system->getMasterName(i));
185 }
186 }
187
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
190 // "non-demand"
191 #define SUM_DEMAND(s) \
192 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + \
193 s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
194
195 // should writebacks be included here? prior code was inconsistent...
196 #define SUM_NON_DEMAND(s) \
197 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
198
199 demandHits
200 .name(name() + ".demand_hits")
201 .desc("number of demand (read+write) hits")
202 .flags(total | nozero | nonan)
203 ;
204 demandHits = SUM_DEMAND(hits);
205 for (int i = 0; i < system->maxMasters(); i++) {
206 demandHits.subname(i, system->getMasterName(i));
207 }
208
209 overallHits
210 .name(name() + ".overall_hits")
211 .desc("number of overall hits")
212 .flags(total | nozero | nonan)
213 ;
214 overallHits = demandHits + SUM_NON_DEMAND(hits);
215 for (int i = 0; i < system->maxMasters(); i++) {
216 overallHits.subname(i, system->getMasterName(i));
217 }
218
219 // Miss statistics
220 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
221 MemCmd cmd(access_idx);
222 const string &cstr = cmd.toString();
223
224 misses[access_idx]
225 .init(system->maxMasters())
226 .name(name() + "." + cstr + "_misses")
227 .desc("number of " + cstr + " misses")
228 .flags(total | nozero | nonan)
229 ;
230 for (int i = 0; i < system->maxMasters(); i++) {
231 misses[access_idx].subname(i, system->getMasterName(i));
232 }
233 }
234
235 demandMisses
236 .name(name() + ".demand_misses")
237 .desc("number of demand (read+write) misses")
238 .flags(total | nozero | nonan)
239 ;
240 demandMisses = SUM_DEMAND(misses);
241 for (int i = 0; i < system->maxMasters(); i++) {
242 demandMisses.subname(i, system->getMasterName(i));
243 }
244
245 overallMisses
246 .name(name() + ".overall_misses")
247 .desc("number of overall misses")
248 .flags(total | nozero | nonan)
249 ;
250 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
251 for (int i = 0; i < system->maxMasters(); i++) {
252 overallMisses.subname(i, system->getMasterName(i));
253 }
254
255 // Miss latency statistics
256 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
257 MemCmd cmd(access_idx);
258 const string &cstr = cmd.toString();
259
260 missLatency[access_idx]
261 .init(system->maxMasters())
262 .name(name() + "." + cstr + "_miss_latency")
263 .desc("number of " + cstr + " miss cycles")
264 .flags(total | nozero | nonan)
265 ;
266 for (int i = 0; i < system->maxMasters(); i++) {
267 missLatency[access_idx].subname(i, system->getMasterName(i));
268 }
269 }
270
271 demandMissLatency
272 .name(name() + ".demand_miss_latency")
273 .desc("number of demand (read+write) miss cycles")
274 .flags(total | nozero | nonan)
275 ;
276 demandMissLatency = SUM_DEMAND(missLatency);
277 for (int i = 0; i < system->maxMasters(); i++) {
278 demandMissLatency.subname(i, system->getMasterName(i));
279 }
280
281 overallMissLatency
282 .name(name() + ".overall_miss_latency")
283 .desc("number of overall miss cycles")
284 .flags(total | nozero | nonan)
285 ;
286 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
287 for (int i = 0; i < system->maxMasters(); i++) {
288 overallMissLatency.subname(i, system->getMasterName(i));
289 }
290
291 // access formulas
292 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
293 MemCmd cmd(access_idx);
294 const string &cstr = cmd.toString();
295
296 accesses[access_idx]
297 .name(name() + "." + cstr + "_accesses")
298 .desc("number of " + cstr + " accesses(hits+misses)")
299 .flags(total | nozero | nonan)
300 ;
301 accesses[access_idx] = hits[access_idx] + misses[access_idx];
302
303 for (int i = 0; i < system->maxMasters(); i++) {
304 accesses[access_idx].subname(i, system->getMasterName(i));
305 }
306 }
307
308 demandAccesses
309 .name(name() + ".demand_accesses")
310 .desc("number of demand (read+write) accesses")
311 .flags(total | nozero | nonan)
312 ;
313 demandAccesses = demandHits + demandMisses;
314 for (int i = 0; i < system->maxMasters(); i++) {
315 demandAccesses.subname(i, system->getMasterName(i));
316 }
317
318 overallAccesses
319 .name(name() + ".overall_accesses")
320 .desc("number of overall (read+write) accesses")
321 .flags(total | nozero | nonan)
322 ;
323 overallAccesses = overallHits + overallMisses;
324 for (int i = 0; i < system->maxMasters(); i++) {
325 overallAccesses.subname(i, system->getMasterName(i));
326 }
327
328 // miss rate formulas
329 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
330 MemCmd cmd(access_idx);
331 const string &cstr = cmd.toString();
332
333 missRate[access_idx]
334 .name(name() + "." + cstr + "_miss_rate")
335 .desc("miss rate for " + cstr + " accesses")
336 .flags(total | nozero | nonan)
337 ;
338 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
339
340 for (int i = 0; i < system->maxMasters(); i++) {
341 missRate[access_idx].subname(i, system->getMasterName(i));
342 }
343 }
344
345 demandMissRate
346 .name(name() + ".demand_miss_rate")
347 .desc("miss rate for demand accesses")
348 .flags(total | nozero | nonan)
349 ;
350 demandMissRate = demandMisses / demandAccesses;
351 for (int i = 0; i < system->maxMasters(); i++) {
352 demandMissRate.subname(i, system->getMasterName(i));
353 }
354
355 overallMissRate
356 .name(name() + ".overall_miss_rate")
357 .desc("miss rate for overall accesses")
358 .flags(total | nozero | nonan)
359 ;
360 overallMissRate = overallMisses / overallAccesses;
361 for (int i = 0; i < system->maxMasters(); i++) {
362 overallMissRate.subname(i, system->getMasterName(i));
363 }
364
365 // miss latency formulas
366 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
367 MemCmd cmd(access_idx);
368 const string &cstr = cmd.toString();
369
370 avgMissLatency[access_idx]
371 .name(name() + "." + cstr + "_avg_miss_latency")
372 .desc("average " + cstr + " miss latency")
373 .flags(total | nozero | nonan)
374 ;
375 avgMissLatency[access_idx] =
376 missLatency[access_idx] / misses[access_idx];
377
378 for (int i = 0; i < system->maxMasters(); i++) {
379 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
380 }
381 }
382
383 demandAvgMissLatency
384 .name(name() + ".demand_avg_miss_latency")
385 .desc("average overall miss latency")
386 .flags(total | nozero | nonan)
387 ;
388 demandAvgMissLatency = demandMissLatency / demandMisses;
389 for (int i = 0; i < system->maxMasters(); i++) {
390 demandAvgMissLatency.subname(i, system->getMasterName(i));
391 }
392
393 overallAvgMissLatency
394 .name(name() + ".overall_avg_miss_latency")
395 .desc("average overall miss latency")
396 .flags(total | nozero | nonan)
397 ;
398 overallAvgMissLatency = overallMissLatency / overallMisses;
399 for (int i = 0; i < system->maxMasters(); i++) {
400 overallAvgMissLatency.subname(i, system->getMasterName(i));
401 }
402
403 blocked_cycles.init(NUM_BLOCKED_CAUSES);
404 blocked_cycles
405 .name(name() + ".blocked_cycles")
406 .desc("number of cycles access was blocked")
407 .subname(Blocked_NoMSHRs, "no_mshrs")
408 .subname(Blocked_NoTargets, "no_targets")
409 ;
410
411
412 blocked_causes.init(NUM_BLOCKED_CAUSES);
413 blocked_causes
414 .name(name() + ".blocked")
415 .desc("number of cycles access was blocked")
416 .subname(Blocked_NoMSHRs, "no_mshrs")
417 .subname(Blocked_NoTargets, "no_targets")
418 ;
419
420 avg_blocked
421 .name(name() + ".avg_blocked_cycles")
422 .desc("average number of cycles each access was blocked")
423 .subname(Blocked_NoMSHRs, "no_mshrs")
424 .subname(Blocked_NoTargets, "no_targets")
425 ;
426
427 avg_blocked = blocked_cycles / blocked_causes;
428
429 fastWrites
430 .name(name() + ".fast_writes")
431 .desc("number of fast writes performed")
432 ;
433
434 cacheCopies
435 .name(name() + ".cache_copies")
436 .desc("number of cache copies performed")
437 ;
438
439 writebacks
440 .init(system->maxMasters())
441 .name(name() + ".writebacks")
442 .desc("number of writebacks")
443 .flags(total | nozero | nonan)
444 ;
445 for (int i = 0; i < system->maxMasters(); i++) {
446 writebacks.subname(i, system->getMasterName(i));
447 }
448
449 // MSHR statistics
450 // MSHR hit statistics
451 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
452 MemCmd cmd(access_idx);
453 const string &cstr = cmd.toString();
454
455 mshr_hits[access_idx]
456 .init(system->maxMasters())
457 .name(name() + "." + cstr + "_mshr_hits")
458 .desc("number of " + cstr + " MSHR hits")
459 .flags(total | nozero | nonan)
460 ;
461 for (int i = 0; i < system->maxMasters(); i++) {
462 mshr_hits[access_idx].subname(i, system->getMasterName(i));
463 }
464 }
465
466 demandMshrHits
467 .name(name() + ".demand_mshr_hits")
468 .desc("number of demand (read+write) MSHR hits")
469 .flags(total | nozero | nonan)
470 ;
471 demandMshrHits = SUM_DEMAND(mshr_hits);
472 for (int i = 0; i < system->maxMasters(); i++) {
473 demandMshrHits.subname(i, system->getMasterName(i));
474 }
475
476 overallMshrHits
477 .name(name() + ".overall_mshr_hits")
478 .desc("number of overall MSHR hits")
479 .flags(total | nozero | nonan)
480 ;
481 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
482 for (int i = 0; i < system->maxMasters(); i++) {
483 overallMshrHits.subname(i, system->getMasterName(i));
484 }
485
486 // MSHR miss statistics
487 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
488 MemCmd cmd(access_idx);
489 const string &cstr = cmd.toString();
490
491 mshr_misses[access_idx]
492 .init(system->maxMasters())
493 .name(name() + "." + cstr + "_mshr_misses")
494 .desc("number of " + cstr + " MSHR misses")
495 .flags(total | nozero | nonan)
496 ;
497 for (int i = 0; i < system->maxMasters(); i++) {
498 mshr_misses[access_idx].subname(i, system->getMasterName(i));
499 }
500 }
501
502 demandMshrMisses
503 .name(name() + ".demand_mshr_misses")
504 .desc("number of demand (read+write) MSHR misses")
505 .flags(total | nozero | nonan)
506 ;
507 demandMshrMisses = SUM_DEMAND(mshr_misses);
508 for (int i = 0; i < system->maxMasters(); i++) {
509 demandMshrMisses.subname(i, system->getMasterName(i));
510 }
511
512 overallMshrMisses
513 .name(name() + ".overall_mshr_misses")
514 .desc("number of overall MSHR misses")
515 .flags(total | nozero | nonan)
516 ;
517 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
518 for (int i = 0; i < system->maxMasters(); i++) {
519 overallMshrMisses.subname(i, system->getMasterName(i));
520 }
521
522 // MSHR miss latency statistics
523 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
524 MemCmd cmd(access_idx);
525 const string &cstr = cmd.toString();
526
527 mshr_miss_latency[access_idx]
528 .init(system->maxMasters())
529 .name(name() + "." + cstr + "_mshr_miss_latency")
530 .desc("number of " + cstr + " MSHR miss cycles")
531 .flags(total | nozero | nonan)
532 ;
533 for (int i = 0; i < system->maxMasters(); i++) {
534 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
535 }
536 }
537
538 demandMshrMissLatency
539 .name(name() + ".demand_mshr_miss_latency")
540 .desc("number of demand (read+write) MSHR miss cycles")
541 .flags(total | nozero | nonan)
542 ;
543 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
544 for (int i = 0; i < system->maxMasters(); i++) {
545 demandMshrMissLatency.subname(i, system->getMasterName(i));
546 }
547
548 overallMshrMissLatency
549 .name(name() + ".overall_mshr_miss_latency")
550 .desc("number of overall MSHR miss cycles")
551 .flags(total | nozero | nonan)
552 ;
553 overallMshrMissLatency =
554 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
555 for (int i = 0; i < system->maxMasters(); i++) {
556 overallMshrMissLatency.subname(i, system->getMasterName(i));
557 }
558
559 // MSHR uncacheable statistics
560 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
561 MemCmd cmd(access_idx);
562 const string &cstr = cmd.toString();
563
564 mshr_uncacheable[access_idx]
565 .init(system->maxMasters())
566 .name(name() + "." + cstr + "_mshr_uncacheable")
567 .desc("number of " + cstr + " MSHR uncacheable")
568 .flags(total | nozero | nonan)
569 ;
570 for (int i = 0; i < system->maxMasters(); i++) {
571 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
572 }
573 }
574
575 overallMshrUncacheable
576 .name(name() + ".overall_mshr_uncacheable_misses")
577 .desc("number of overall MSHR uncacheable misses")
578 .flags(total | nozero | nonan)
579 ;
580 overallMshrUncacheable =
581 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
582 for (int i = 0; i < system->maxMasters(); i++) {
583 overallMshrUncacheable.subname(i, system->getMasterName(i));
584 }
585
586 // MSHR miss latency statistics
587 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
588 MemCmd cmd(access_idx);
589 const string &cstr = cmd.toString();
590
591 mshr_uncacheable_lat[access_idx]
592 .init(system->maxMasters())
593 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
594 .desc("number of " + cstr + " MSHR uncacheable cycles")
595 .flags(total | nozero | nonan)
596 ;
597 for (int i = 0; i < system->maxMasters(); i++) {
598 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
599 }
600 }
601
602 overallMshrUncacheableLatency
603 .name(name() + ".overall_mshr_uncacheable_latency")
604 .desc("number of overall MSHR uncacheable cycles")
605 .flags(total | nozero | nonan)
606 ;
607 overallMshrUncacheableLatency =
608 SUM_DEMAND(mshr_uncacheable_lat) +
609 SUM_NON_DEMAND(mshr_uncacheable_lat);
610 for (int i = 0; i < system->maxMasters(); i++) {
611 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
612 }
613
614 #if 0
615 // MSHR access formulas
616 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
617 MemCmd cmd(access_idx);
618 const string &cstr = cmd.toString();
619
620 mshrAccesses[access_idx]
621 .name(name() + "." + cstr + "_mshr_accesses")
622 .desc("number of " + cstr + " mshr accesses(hits+misses)")
623 .flags(total | nozero | nonan)
624 ;
625 mshrAccesses[access_idx] =
626 mshr_hits[access_idx] + mshr_misses[access_idx]
627 + mshr_uncacheable[access_idx];
628 }
629
630 demandMshrAccesses
631 .name(name() + ".demand_mshr_accesses")
632 .desc("number of demand (read+write) mshr accesses")
633 .flags(total | nozero | nonan)
634 ;
635 demandMshrAccesses = demandMshrHits + demandMshrMisses;
636
637 overallMshrAccesses
638 .name(name() + ".overall_mshr_accesses")
639 .desc("number of overall (read+write) mshr accesses")
640 .flags(total | nozero | nonan)
641 ;
642 overallMshrAccesses = overallMshrHits + overallMshrMisses
643 + overallMshrUncacheable;
644 #endif
645
646 // MSHR miss rate formulas
647 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
648 MemCmd cmd(access_idx);
649 const string &cstr = cmd.toString();
650
651 mshrMissRate[access_idx]
652 .name(name() + "." + cstr + "_mshr_miss_rate")
653 .desc("mshr miss rate for " + cstr + " accesses")
654 .flags(total | nozero | nonan)
655 ;
656 mshrMissRate[access_idx] =
657 mshr_misses[access_idx] / accesses[access_idx];
658
659 for (int i = 0; i < system->maxMasters(); i++) {
660 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
661 }
662 }
663
664 demandMshrMissRate
665 .name(name() + ".demand_mshr_miss_rate")
666 .desc("mshr miss rate for demand accesses")
667 .flags(total | nozero | nonan)
668 ;
669 demandMshrMissRate = demandMshrMisses / demandAccesses;
670 for (int i = 0; i < system->maxMasters(); i++) {
671 demandMshrMissRate.subname(i, system->getMasterName(i));
672 }
673
674 overallMshrMissRate
675 .name(name() + ".overall_mshr_miss_rate")
676 .desc("mshr miss rate for overall accesses")
677 .flags(total | nozero | nonan)
678 ;
679 overallMshrMissRate = overallMshrMisses / overallAccesses;
680 for (int i = 0; i < system->maxMasters(); i++) {
681 overallMshrMissRate.subname(i, system->getMasterName(i));
682 }
683
684 // mshrMiss latency formulas
685 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
686 MemCmd cmd(access_idx);
687 const string &cstr = cmd.toString();
688
689 avgMshrMissLatency[access_idx]
690 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
691 .desc("average " + cstr + " mshr miss latency")
692 .flags(total | nozero | nonan)
693 ;
694 avgMshrMissLatency[access_idx] =
695 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
696
697 for (int i = 0; i < system->maxMasters(); i++) {
698 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
699 }
700 }
701
702 demandAvgMshrMissLatency
703 .name(name() + ".demand_avg_mshr_miss_latency")
704 .desc("average overall mshr miss latency")
705 .flags(total | nozero | nonan)
706 ;
707 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
708 for (int i = 0; i < system->maxMasters(); i++) {
709 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
710 }
711
712 overallAvgMshrMissLatency
713 .name(name() + ".overall_avg_mshr_miss_latency")
714 .desc("average overall mshr miss latency")
715 .flags(total | nozero | nonan)
716 ;
717 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
718 for (int i = 0; i < system->maxMasters(); i++) {
719 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
720 }
721
722 // mshrUncacheable latency formulas
723 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
724 MemCmd cmd(access_idx);
725 const string &cstr = cmd.toString();
726
727 avgMshrUncacheableLatency[access_idx]
728 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
729 .desc("average " + cstr + " mshr uncacheable latency")
730 .flags(total | nozero | nonan)
731 ;
732 avgMshrUncacheableLatency[access_idx] =
733 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
734
735 for (int i = 0; i < system->maxMasters(); i++) {
736 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
737 }
738 }
739
740 overallAvgMshrUncacheableLatency
741 .name(name() + ".overall_avg_mshr_uncacheable_latency")
742 .desc("average overall mshr uncacheable latency")
743 .flags(total | nozero | nonan)
744 ;
745 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
746 for (int i = 0; i < system->maxMasters(); i++) {
747 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
748 }
749
750 mshr_cap_events
751 .init(system->maxMasters())
752 .name(name() + ".mshr_cap_events")
753 .desc("number of times MSHR cap was activated")
754 .flags(total | nozero | nonan)
755 ;
756 for (int i = 0; i < system->maxMasters(); i++) {
757 mshr_cap_events.subname(i, system->getMasterName(i));
758 }
759
760 //software prefetching stats
761 soft_prefetch_mshr_full
762 .init(system->maxMasters())
763 .name(name() + ".soft_prefetch_mshr_full")
764 .desc("number of mshr full events for SW prefetching instrutions")
765 .flags(total | nozero | nonan)
766 ;
767 for (int i = 0; i < system->maxMasters(); i++) {
768 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
769 }
770
771 mshr_no_allocate_misses
772 .name(name() +".no_allocate_misses")
773 .desc("Number of misses that were no-allocate")
774 ;
775
776 }
777
778 unsigned int
779 BaseCache::drain(DrainManager *dm)
780 {
781 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
782 mshrQueue.drain(dm) + writeBuffer.drain(dm);
783
784 // Set status
785 if (count != 0) {
786 setDrainState(DrainState::Draining);
787 DPRINTF(Drain, "Cache not drained\n");
788 return count;
789 }
790
791 setDrainState(DrainState::Drained);
792 return 0;
793 }
794
795 BaseCache *
796 BaseCacheParams::create()
797 {
798 assert(tags);
799
800 return new Cache(this);
801 }