Deleted Added
sdiff udiff text old ( 10622:0b969a35781f ) new ( 10693:c0979b2ebda5 )
full compact
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
58using namespace std;
59
60BaseCache::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
68BaseCache::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 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),
80 blocked(0),
81 order(0),
82 noTargetMSHR(NULL),
83 missCount(p->max_miss_count),
84 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
85 system(p->system)
86{
87}
88
89void
90BaseCache::CacheSlavePort::setBlocked()
91{
92 assert(!blocked);
93 DPRINTF(CachePort, "Cache port %s blocking new requests\n", name());
94 blocked = true;
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;
101 }
102}
103
104void
105BaseCache::CacheSlavePort::clearBlocked()
106{
107 assert(blocked);
108 DPRINTF(CachePort, "Cache port %s accepting new requests\n", name());
109 blocked = false;
110 if (mustSendRetry) {
111 // @TODO: need to find a better time (next bus cycle?)
112 owner.schedule(sendRetryEvent, curTick() + 1);
113 }
114}
115
116void
117BaseCache::CacheSlavePort::processSendRetry()
118{
119 DPRINTF(CachePort, "Cache port %s sending retry\n", name());
120
121 // reset the flag and call retry
122 mustSendRetry = false;
123 sendRetry();
124}
125
126void
127BaseCache::init()
128{
129 if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
130 fatal("Cache ports on %s are not connected\n", name());
131 cpuSidePort->sendRangeChange();
132}
133
134BaseMasterPort &
135BaseCache::getMasterPort(const std::string &if_name, PortID idx)
136{
137 if (if_name == "mem_side") {
138 return *memSidePort;
139 } else {
140 return MemObject::getMasterPort(if_name, idx);
141 }
142}
143
144BaseSlavePort &
145BaseCache::getSlavePort(const std::string &if_name, PortID idx)
146{
147 if (if_name == "cpu_side") {
148 return *cpuSidePort;
149 } else {
150 return MemObject::getSlavePort(if_name, idx);
151 }
152}
153
154void
155BaseCache::regStats()
156{
157 using namespace Stats;
158
159 // Hit statistics
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();
163
164 hits[access_idx]
165 .init(system->maxMasters())
166 .name(name() + "." + cstr + "_hits")
167 .desc("number of " + cstr + " hits")
168 .flags(total | nozero | nonan)
169 ;
170 for (int i = 0; i < system->maxMasters(); i++) {
171 hits[access_idx].subname(i, system->getMasterName(i));
172 }
173 }
174
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
177// "non-demand"
178#define SUM_DEMAND(s) \
179 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
180
181// should writebacks be included here? prior code was inconsistent...
182#define SUM_NON_DEMAND(s) \
183 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
184
185 demandHits
186 .name(name() + ".demand_hits")
187 .desc("number of demand (read+write) hits")
188 .flags(total | nozero | nonan)
189 ;
190 demandHits = SUM_DEMAND(hits);
191 for (int i = 0; i < system->maxMasters(); i++) {
192 demandHits.subname(i, system->getMasterName(i));
193 }
194
195 overallHits
196 .name(name() + ".overall_hits")
197 .desc("number of overall hits")
198 .flags(total | nozero | nonan)
199 ;
200 overallHits = demandHits + SUM_NON_DEMAND(hits);
201 for (int i = 0; i < system->maxMasters(); i++) {
202 overallHits.subname(i, system->getMasterName(i));
203 }
204
205 // Miss statistics
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();
209
210 misses[access_idx]
211 .init(system->maxMasters())
212 .name(name() + "." + cstr + "_misses")
213 .desc("number of " + cstr + " misses")
214 .flags(total | nozero | nonan)
215 ;
216 for (int i = 0; i < system->maxMasters(); i++) {
217 misses[access_idx].subname(i, system->getMasterName(i));
218 }
219 }
220
221 demandMisses
222 .name(name() + ".demand_misses")
223 .desc("number of demand (read+write) misses")
224 .flags(total | nozero | nonan)
225 ;
226 demandMisses = SUM_DEMAND(misses);
227 for (int i = 0; i < system->maxMasters(); i++) {
228 demandMisses.subname(i, system->getMasterName(i));
229 }
230
231 overallMisses
232 .name(name() + ".overall_misses")
233 .desc("number of overall misses")
234 .flags(total | nozero | nonan)
235 ;
236 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
237 for (int i = 0; i < system->maxMasters(); i++) {
238 overallMisses.subname(i, system->getMasterName(i));
239 }
240
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();
245
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)
251 ;
252 for (int i = 0; i < system->maxMasters(); i++) {
253 missLatency[access_idx].subname(i, system->getMasterName(i));
254 }
255 }
256
257 demandMissLatency
258 .name(name() + ".demand_miss_latency")
259 .desc("number of demand (read+write) miss cycles")
260 .flags(total | nozero | nonan)
261 ;
262 demandMissLatency = SUM_DEMAND(missLatency);
263 for (int i = 0; i < system->maxMasters(); i++) {
264 demandMissLatency.subname(i, system->getMasterName(i));
265 }
266
267 overallMissLatency
268 .name(name() + ".overall_miss_latency")
269 .desc("number of overall miss cycles")
270 .flags(total | nozero | nonan)
271 ;
272 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
273 for (int i = 0; i < system->maxMasters(); i++) {
274 overallMissLatency.subname(i, system->getMasterName(i));
275 }
276
277 // access formulas
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();
281
282 accesses[access_idx]
283 .name(name() + "." + cstr + "_accesses")
284 .desc("number of " + cstr + " accesses(hits+misses)")
285 .flags(total | nozero | nonan)
286 ;
287 accesses[access_idx] = hits[access_idx] + misses[access_idx];
288
289 for (int i = 0; i < system->maxMasters(); i++) {
290 accesses[access_idx].subname(i, system->getMasterName(i));
291 }
292 }
293
294 demandAccesses
295 .name(name() + ".demand_accesses")
296 .desc("number of demand (read+write) accesses")
297 .flags(total | nozero | nonan)
298 ;
299 demandAccesses = demandHits + demandMisses;
300 for (int i = 0; i < system->maxMasters(); i++) {
301 demandAccesses.subname(i, system->getMasterName(i));
302 }
303
304 overallAccesses
305 .name(name() + ".overall_accesses")
306 .desc("number of overall (read+write) accesses")
307 .flags(total | nozero | nonan)
308 ;
309 overallAccesses = overallHits + overallMisses;
310 for (int i = 0; i < system->maxMasters(); i++) {
311 overallAccesses.subname(i, system->getMasterName(i));
312 }
313
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();
318
319 missRate[access_idx]
320 .name(name() + "." + cstr + "_miss_rate")
321 .desc("miss rate for " + cstr + " accesses")
322 .flags(total | nozero | nonan)
323 ;
324 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
325
326 for (int i = 0; i < system->maxMasters(); i++) {
327 missRate[access_idx].subname(i, system->getMasterName(i));
328 }
329 }
330
331 demandMissRate
332 .name(name() + ".demand_miss_rate")
333 .desc("miss rate for demand accesses")
334 .flags(total | nozero | nonan)
335 ;
336 demandMissRate = demandMisses / demandAccesses;
337 for (int i = 0; i < system->maxMasters(); i++) {
338 demandMissRate.subname(i, system->getMasterName(i));
339 }
340
341 overallMissRate
342 .name(name() + ".overall_miss_rate")
343 .desc("miss rate for overall accesses")
344 .flags(total | nozero | nonan)
345 ;
346 overallMissRate = overallMisses / overallAccesses;
347 for (int i = 0; i < system->maxMasters(); i++) {
348 overallMissRate.subname(i, system->getMasterName(i));
349 }
350
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();
355
356 avgMissLatency[access_idx]
357 .name(name() + "." + cstr + "_avg_miss_latency")
358 .desc("average " + cstr + " miss latency")
359 .flags(total | nozero | nonan)
360 ;
361 avgMissLatency[access_idx] =
362 missLatency[access_idx] / misses[access_idx];
363
364 for (int i = 0; i < system->maxMasters(); i++) {
365 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
366 }
367 }
368
369 demandAvgMissLatency
370 .name(name() + ".demand_avg_miss_latency")
371 .desc("average overall miss latency")
372 .flags(total | nozero | nonan)
373 ;
374 demandAvgMissLatency = demandMissLatency / demandMisses;
375 for (int i = 0; i < system->maxMasters(); i++) {
376 demandAvgMissLatency.subname(i, system->getMasterName(i));
377 }
378
379 overallAvgMissLatency
380 .name(name() + ".overall_avg_miss_latency")
381 .desc("average overall miss latency")
382 .flags(total | nozero | nonan)
383 ;
384 overallAvgMissLatency = overallMissLatency / overallMisses;
385 for (int i = 0; i < system->maxMasters(); i++) {
386 overallAvgMissLatency.subname(i, system->getMasterName(i));
387 }
388
389 blocked_cycles.init(NUM_BLOCKED_CAUSES);
390 blocked_cycles
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")
395 ;
396
397
398 blocked_causes.init(NUM_BLOCKED_CAUSES);
399 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")
404 ;
405
406 avg_blocked
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")
411 ;
412
413 avg_blocked = blocked_cycles / blocked_causes;
414
415 fastWrites
416 .name(name() + ".fast_writes")
417 .desc("number of fast writes performed")
418 ;
419
420 cacheCopies
421 .name(name() + ".cache_copies")
422 .desc("number of cache copies performed")
423 ;
424
425 writebacks
426 .init(system->maxMasters())
427 .name(name() + ".writebacks")
428 .desc("number of writebacks")
429 .flags(total | nozero | nonan)
430 ;
431 for (int i = 0; i < system->maxMasters(); i++) {
432 writebacks.subname(i, system->getMasterName(i));
433 }
434
435 // MSHR statistics
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();
440
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)
446 ;
447 for (int i = 0; i < system->maxMasters(); i++) {
448 mshr_hits[access_idx].subname(i, system->getMasterName(i));
449 }
450 }
451
452 demandMshrHits
453 .name(name() + ".demand_mshr_hits")
454 .desc("number of demand (read+write) MSHR hits")
455 .flags(total | nozero | nonan)
456 ;
457 demandMshrHits = SUM_DEMAND(mshr_hits);
458 for (int i = 0; i < system->maxMasters(); i++) {
459 demandMshrHits.subname(i, system->getMasterName(i));
460 }
461
462 overallMshrHits
463 .name(name() + ".overall_mshr_hits")
464 .desc("number of overall MSHR hits")
465 .flags(total | nozero | nonan)
466 ;
467 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
468 for (int i = 0; i < system->maxMasters(); i++) {
469 overallMshrHits.subname(i, system->getMasterName(i));
470 }
471
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();
476
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)
482 ;
483 for (int i = 0; i < system->maxMasters(); i++) {
484 mshr_misses[access_idx].subname(i, system->getMasterName(i));
485 }
486 }
487
488 demandMshrMisses
489 .name(name() + ".demand_mshr_misses")
490 .desc("number of demand (read+write) MSHR misses")
491 .flags(total | nozero | nonan)
492 ;
493 demandMshrMisses = SUM_DEMAND(mshr_misses);
494 for (int i = 0; i < system->maxMasters(); i++) {
495 demandMshrMisses.subname(i, system->getMasterName(i));
496 }
497
498 overallMshrMisses
499 .name(name() + ".overall_mshr_misses")
500 .desc("number of overall MSHR misses")
501 .flags(total | nozero | nonan)
502 ;
503 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
504 for (int i = 0; i < system->maxMasters(); i++) {
505 overallMshrMisses.subname(i, system->getMasterName(i));
506 }
507
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();
512
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)
518 ;
519 for (int i = 0; i < system->maxMasters(); i++) {
520 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
521 }
522 }
523
524 demandMshrMissLatency
525 .name(name() + ".demand_mshr_miss_latency")
526 .desc("number of demand (read+write) MSHR miss cycles")
527 .flags(total | nozero | nonan)
528 ;
529 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
530 for (int i = 0; i < system->maxMasters(); i++) {
531 demandMshrMissLatency.subname(i, system->getMasterName(i));
532 }
533
534 overallMshrMissLatency
535 .name(name() + ".overall_mshr_miss_latency")
536 .desc("number of overall MSHR miss cycles")
537 .flags(total | nozero | nonan)
538 ;
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));
543 }
544
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();
549
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)
555 ;
556 for (int i = 0; i < system->maxMasters(); i++) {
557 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
558 }
559 }
560
561 overallMshrUncacheable
562 .name(name() + ".overall_mshr_uncacheable_misses")
563 .desc("number of overall MSHR uncacheable misses")
564 .flags(total | nozero | nonan)
565 ;
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));
570 }
571
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();
576
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)
582 ;
583 for (int i = 0; i < system->maxMasters(); i++) {
584 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
585 }
586 }
587
588 overallMshrUncacheableLatency
589 .name(name() + ".overall_mshr_uncacheable_latency")
590 .desc("number of overall MSHR uncacheable cycles")
591 .flags(total | nozero | nonan)
592 ;
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));
598 }
599
600#if 0
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();
605
606 mshrAccesses[access_idx]
607 .name(name() + "." + cstr + "_mshr_accesses")
608 .desc("number of " + cstr + " mshr accesses(hits+misses)")
609 .flags(total | nozero | nonan)
610 ;
611 mshrAccesses[access_idx] =
612 mshr_hits[access_idx] + mshr_misses[access_idx]
613 + mshr_uncacheable[access_idx];
614 }
615
616 demandMshrAccesses
617 .name(name() + ".demand_mshr_accesses")
618 .desc("number of demand (read+write) mshr accesses")
619 .flags(total | nozero | nonan)
620 ;
621 demandMshrAccesses = demandMshrHits + demandMshrMisses;
622
623 overallMshrAccesses
624 .name(name() + ".overall_mshr_accesses")
625 .desc("number of overall (read+write) mshr accesses")
626 .flags(total | nozero | nonan)
627 ;
628 overallMshrAccesses = overallMshrHits + overallMshrMisses
629 + overallMshrUncacheable;
630#endif
631
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();
636
637 mshrMissRate[access_idx]
638 .name(name() + "." + cstr + "_mshr_miss_rate")
639 .desc("mshr miss rate for " + cstr + " accesses")
640 .flags(total | nozero | nonan)
641 ;
642 mshrMissRate[access_idx] =
643 mshr_misses[access_idx] / accesses[access_idx];
644
645 for (int i = 0; i < system->maxMasters(); i++) {
646 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
647 }
648 }
649
650 demandMshrMissRate
651 .name(name() + ".demand_mshr_miss_rate")
652 .desc("mshr miss rate for demand accesses")
653 .flags(total | nozero | nonan)
654 ;
655 demandMshrMissRate = demandMshrMisses / demandAccesses;
656 for (int i = 0; i < system->maxMasters(); i++) {
657 demandMshrMissRate.subname(i, system->getMasterName(i));
658 }
659
660 overallMshrMissRate
661 .name(name() + ".overall_mshr_miss_rate")
662 .desc("mshr miss rate for overall accesses")
663 .flags(total | nozero | nonan)
664 ;
665 overallMshrMissRate = overallMshrMisses / overallAccesses;
666 for (int i = 0; i < system->maxMasters(); i++) {
667 overallMshrMissRate.subname(i, system->getMasterName(i));
668 }
669
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();
674
675 avgMshrMissLatency[access_idx]
676 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
677 .desc("average " + cstr + " mshr miss latency")
678 .flags(total | nozero | nonan)
679 ;
680 avgMshrMissLatency[access_idx] =
681 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
682
683 for (int i = 0; i < system->maxMasters(); i++) {
684 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
685 }
686 }
687
688 demandAvgMshrMissLatency
689 .name(name() + ".demand_avg_mshr_miss_latency")
690 .desc("average overall mshr miss latency")
691 .flags(total | nozero | nonan)
692 ;
693 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
694 for (int i = 0; i < system->maxMasters(); i++) {
695 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
696 }
697
698 overallAvgMshrMissLatency
699 .name(name() + ".overall_avg_mshr_miss_latency")
700 .desc("average overall mshr miss latency")
701 .flags(total | nozero | nonan)
702 ;
703 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
704 for (int i = 0; i < system->maxMasters(); i++) {
705 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
706 }
707
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();
712
713 avgMshrUncacheableLatency[access_idx]
714 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
715 .desc("average " + cstr + " mshr uncacheable latency")
716 .flags(total | nozero | nonan)
717 ;
718 avgMshrUncacheableLatency[access_idx] =
719 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
720
721 for (int i = 0; i < system->maxMasters(); i++) {
722 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
723 }
724 }
725
726 overallAvgMshrUncacheableLatency
727 .name(name() + ".overall_avg_mshr_uncacheable_latency")
728 .desc("average overall mshr uncacheable latency")
729 .flags(total | nozero | nonan)
730 ;
731 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
732 for (int i = 0; i < system->maxMasters(); i++) {
733 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
734 }
735
736 mshr_cap_events
737 .init(system->maxMasters())
738 .name(name() + ".mshr_cap_events")
739 .desc("number of times MSHR cap was activated")
740 .flags(total | nozero | nonan)
741 ;
742 for (int i = 0; i < system->maxMasters(); i++) {
743 mshr_cap_events.subname(i, system->getMasterName(i));
744 }
745
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)
752 ;
753 for (int i = 0; i < system->maxMasters(); i++) {
754 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
755 }
756
757 mshr_no_allocate_misses
758 .name(name() +".no_allocate_misses")
759 .desc("Number of misses that were no-allocate")
760 ;
761
762}
763
764unsigned int
765BaseCache::drain(DrainManager *dm)
766{
767 int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
768 mshrQueue.drain(dm) + writeBuffer.drain(dm);
769
770 // Set status
771 if (count != 0) {
772 setDrainState(Drainable::Draining);
773 DPRINTF(Drain, "Cache not drained\n");
774 return count;
775 }
776
777 setDrainState(Drainable::Drained);
778 return 0;
779}
780
781BaseCache *
782BaseCacheParams::create()
783{
784 unsigned numSets = size / (assoc * system->cacheLineSize());
785
786 assert(tags);
787
788 if (dynamic_cast<FALRU*>(tags)) {
789 if (numSets != 1)
790 fatal("Got FALRU tags with more than one set\n");
791 return new Cache<FALRU>(this);
792 } else if (dynamic_cast<LRU*>(tags)) {
793 if (numSets == 1)
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);
798 } else {
799 fatal("No suitable tags selected\n");
800 }
801}