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