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