base.cc (11455:067177a1b578) base.cc (11483:d4c2e56d18b2)
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] + s[MemCmd::WriteLineReq] + \
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 unusedPrefetches
438 .name(name() + ".unused_prefetches")
439 .desc("number of HardPF blocks evicted w/o reference")
440 .flags(nozero)
441 ;
442
443 writebacks
444 .init(system->maxMasters())
445 .name(name() + ".writebacks")
446 .desc("number of writebacks")
447 .flags(total | nozero | nonan)
448 ;
449 for (int i = 0; i < system->maxMasters(); i++) {
450 writebacks.subname(i, system->getMasterName(i));
451 }
452
453 // MSHR statistics
454 // MSHR hit statistics
455 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
456 MemCmd cmd(access_idx);
457 const string &cstr = cmd.toString();
458
459 mshr_hits[access_idx]
460 .init(system->maxMasters())
461 .name(name() + "." + cstr + "_mshr_hits")
462 .desc("number of " + cstr + " MSHR hits")
463 .flags(total | nozero | nonan)
464 ;
465 for (int i = 0; i < system->maxMasters(); i++) {
466 mshr_hits[access_idx].subname(i, system->getMasterName(i));
467 }
468 }
469
470 demandMshrHits
471 .name(name() + ".demand_mshr_hits")
472 .desc("number of demand (read+write) MSHR hits")
473 .flags(total | nozero | nonan)
474 ;
475 demandMshrHits = SUM_DEMAND(mshr_hits);
476 for (int i = 0; i < system->maxMasters(); i++) {
477 demandMshrHits.subname(i, system->getMasterName(i));
478 }
479
480 overallMshrHits
481 .name(name() + ".overall_mshr_hits")
482 .desc("number of overall MSHR hits")
483 .flags(total | nozero | nonan)
484 ;
485 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
486 for (int i = 0; i < system->maxMasters(); i++) {
487 overallMshrHits.subname(i, system->getMasterName(i));
488 }
489
490 // MSHR miss statistics
491 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
492 MemCmd cmd(access_idx);
493 const string &cstr = cmd.toString();
494
495 mshr_misses[access_idx]
496 .init(system->maxMasters())
497 .name(name() + "." + cstr + "_mshr_misses")
498 .desc("number of " + cstr + " MSHR misses")
499 .flags(total | nozero | nonan)
500 ;
501 for (int i = 0; i < system->maxMasters(); i++) {
502 mshr_misses[access_idx].subname(i, system->getMasterName(i));
503 }
504 }
505
506 demandMshrMisses
507 .name(name() + ".demand_mshr_misses")
508 .desc("number of demand (read+write) MSHR misses")
509 .flags(total | nozero | nonan)
510 ;
511 demandMshrMisses = SUM_DEMAND(mshr_misses);
512 for (int i = 0; i < system->maxMasters(); i++) {
513 demandMshrMisses.subname(i, system->getMasterName(i));
514 }
515
516 overallMshrMisses
517 .name(name() + ".overall_mshr_misses")
518 .desc("number of overall MSHR misses")
519 .flags(total | nozero | nonan)
520 ;
521 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
522 for (int i = 0; i < system->maxMasters(); i++) {
523 overallMshrMisses.subname(i, system->getMasterName(i));
524 }
525
526 // MSHR miss latency statistics
527 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
528 MemCmd cmd(access_idx);
529 const string &cstr = cmd.toString();
530
531 mshr_miss_latency[access_idx]
532 .init(system->maxMasters())
533 .name(name() + "." + cstr + "_mshr_miss_latency")
534 .desc("number of " + cstr + " MSHR miss cycles")
535 .flags(total | nozero | nonan)
536 ;
537 for (int i = 0; i < system->maxMasters(); i++) {
538 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
539 }
540 }
541
542 demandMshrMissLatency
543 .name(name() + ".demand_mshr_miss_latency")
544 .desc("number of demand (read+write) MSHR miss cycles")
545 .flags(total | nozero | nonan)
546 ;
547 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
548 for (int i = 0; i < system->maxMasters(); i++) {
549 demandMshrMissLatency.subname(i, system->getMasterName(i));
550 }
551
552 overallMshrMissLatency
553 .name(name() + ".overall_mshr_miss_latency")
554 .desc("number of overall MSHR miss cycles")
555 .flags(total | nozero | nonan)
556 ;
557 overallMshrMissLatency =
558 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
559 for (int i = 0; i < system->maxMasters(); i++) {
560 overallMshrMissLatency.subname(i, system->getMasterName(i));
561 }
562
563 // MSHR uncacheable statistics
564 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
565 MemCmd cmd(access_idx);
566 const string &cstr = cmd.toString();
567
568 mshr_uncacheable[access_idx]
569 .init(system->maxMasters())
570 .name(name() + "." + cstr + "_mshr_uncacheable")
571 .desc("number of " + cstr + " MSHR uncacheable")
572 .flags(total | nozero | nonan)
573 ;
574 for (int i = 0; i < system->maxMasters(); i++) {
575 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
576 }
577 }
578
579 overallMshrUncacheable
580 .name(name() + ".overall_mshr_uncacheable_misses")
581 .desc("number of overall MSHR uncacheable misses")
582 .flags(total | nozero | nonan)
583 ;
584 overallMshrUncacheable =
585 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
586 for (int i = 0; i < system->maxMasters(); i++) {
587 overallMshrUncacheable.subname(i, system->getMasterName(i));
588 }
589
590 // MSHR miss latency statistics
591 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
592 MemCmd cmd(access_idx);
593 const string &cstr = cmd.toString();
594
595 mshr_uncacheable_lat[access_idx]
596 .init(system->maxMasters())
597 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
598 .desc("number of " + cstr + " MSHR uncacheable cycles")
599 .flags(total | nozero | nonan)
600 ;
601 for (int i = 0; i < system->maxMasters(); i++) {
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] + s[MemCmd::WriteLineReq] + \
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 unusedPrefetches
438 .name(name() + ".unused_prefetches")
439 .desc("number of HardPF blocks evicted w/o reference")
440 .flags(nozero)
441 ;
442
443 writebacks
444 .init(system->maxMasters())
445 .name(name() + ".writebacks")
446 .desc("number of writebacks")
447 .flags(total | nozero | nonan)
448 ;
449 for (int i = 0; i < system->maxMasters(); i++) {
450 writebacks.subname(i, system->getMasterName(i));
451 }
452
453 // MSHR statistics
454 // MSHR hit statistics
455 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
456 MemCmd cmd(access_idx);
457 const string &cstr = cmd.toString();
458
459 mshr_hits[access_idx]
460 .init(system->maxMasters())
461 .name(name() + "." + cstr + "_mshr_hits")
462 .desc("number of " + cstr + " MSHR hits")
463 .flags(total | nozero | nonan)
464 ;
465 for (int i = 0; i < system->maxMasters(); i++) {
466 mshr_hits[access_idx].subname(i, system->getMasterName(i));
467 }
468 }
469
470 demandMshrHits
471 .name(name() + ".demand_mshr_hits")
472 .desc("number of demand (read+write) MSHR hits")
473 .flags(total | nozero | nonan)
474 ;
475 demandMshrHits = SUM_DEMAND(mshr_hits);
476 for (int i = 0; i < system->maxMasters(); i++) {
477 demandMshrHits.subname(i, system->getMasterName(i));
478 }
479
480 overallMshrHits
481 .name(name() + ".overall_mshr_hits")
482 .desc("number of overall MSHR hits")
483 .flags(total | nozero | nonan)
484 ;
485 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
486 for (int i = 0; i < system->maxMasters(); i++) {
487 overallMshrHits.subname(i, system->getMasterName(i));
488 }
489
490 // MSHR miss statistics
491 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
492 MemCmd cmd(access_idx);
493 const string &cstr = cmd.toString();
494
495 mshr_misses[access_idx]
496 .init(system->maxMasters())
497 .name(name() + "." + cstr + "_mshr_misses")
498 .desc("number of " + cstr + " MSHR misses")
499 .flags(total | nozero | nonan)
500 ;
501 for (int i = 0; i < system->maxMasters(); i++) {
502 mshr_misses[access_idx].subname(i, system->getMasterName(i));
503 }
504 }
505
506 demandMshrMisses
507 .name(name() + ".demand_mshr_misses")
508 .desc("number of demand (read+write) MSHR misses")
509 .flags(total | nozero | nonan)
510 ;
511 demandMshrMisses = SUM_DEMAND(mshr_misses);
512 for (int i = 0; i < system->maxMasters(); i++) {
513 demandMshrMisses.subname(i, system->getMasterName(i));
514 }
515
516 overallMshrMisses
517 .name(name() + ".overall_mshr_misses")
518 .desc("number of overall MSHR misses")
519 .flags(total | nozero | nonan)
520 ;
521 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
522 for (int i = 0; i < system->maxMasters(); i++) {
523 overallMshrMisses.subname(i, system->getMasterName(i));
524 }
525
526 // MSHR miss latency statistics
527 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
528 MemCmd cmd(access_idx);
529 const string &cstr = cmd.toString();
530
531 mshr_miss_latency[access_idx]
532 .init(system->maxMasters())
533 .name(name() + "." + cstr + "_mshr_miss_latency")
534 .desc("number of " + cstr + " MSHR miss cycles")
535 .flags(total | nozero | nonan)
536 ;
537 for (int i = 0; i < system->maxMasters(); i++) {
538 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
539 }
540 }
541
542 demandMshrMissLatency
543 .name(name() + ".demand_mshr_miss_latency")
544 .desc("number of demand (read+write) MSHR miss cycles")
545 .flags(total | nozero | nonan)
546 ;
547 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
548 for (int i = 0; i < system->maxMasters(); i++) {
549 demandMshrMissLatency.subname(i, system->getMasterName(i));
550 }
551
552 overallMshrMissLatency
553 .name(name() + ".overall_mshr_miss_latency")
554 .desc("number of overall MSHR miss cycles")
555 .flags(total | nozero | nonan)
556 ;
557 overallMshrMissLatency =
558 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
559 for (int i = 0; i < system->maxMasters(); i++) {
560 overallMshrMissLatency.subname(i, system->getMasterName(i));
561 }
562
563 // MSHR uncacheable statistics
564 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
565 MemCmd cmd(access_idx);
566 const string &cstr = cmd.toString();
567
568 mshr_uncacheable[access_idx]
569 .init(system->maxMasters())
570 .name(name() + "." + cstr + "_mshr_uncacheable")
571 .desc("number of " + cstr + " MSHR uncacheable")
572 .flags(total | nozero | nonan)
573 ;
574 for (int i = 0; i < system->maxMasters(); i++) {
575 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
576 }
577 }
578
579 overallMshrUncacheable
580 .name(name() + ".overall_mshr_uncacheable_misses")
581 .desc("number of overall MSHR uncacheable misses")
582 .flags(total | nozero | nonan)
583 ;
584 overallMshrUncacheable =
585 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
586 for (int i = 0; i < system->maxMasters(); i++) {
587 overallMshrUncacheable.subname(i, system->getMasterName(i));
588 }
589
590 // MSHR miss latency statistics
591 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
592 MemCmd cmd(access_idx);
593 const string &cstr = cmd.toString();
594
595 mshr_uncacheable_lat[access_idx]
596 .init(system->maxMasters())
597 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
598 .desc("number of " + cstr + " MSHR uncacheable cycles")
599 .flags(total | nozero | nonan)
600 ;
601 for (int i = 0; i < system->maxMasters(); i++) {
602 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
602 mshr_uncacheable_lat[access_idx].subname(
603 i, system->getMasterName(i));
603 }
604 }
605
606 overallMshrUncacheableLatency
607 .name(name() + ".overall_mshr_uncacheable_latency")
608 .desc("number of overall MSHR uncacheable cycles")
609 .flags(total | nozero | nonan)
610 ;
611 overallMshrUncacheableLatency =
612 SUM_DEMAND(mshr_uncacheable_lat) +
613 SUM_NON_DEMAND(mshr_uncacheable_lat);
614 for (int i = 0; i < system->maxMasters(); i++) {
615 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
616 }
617
618#if 0
619 // MSHR access formulas
620 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
621 MemCmd cmd(access_idx);
622 const string &cstr = cmd.toString();
623
624 mshrAccesses[access_idx]
625 .name(name() + "." + cstr + "_mshr_accesses")
626 .desc("number of " + cstr + " mshr accesses(hits+misses)")
627 .flags(total | nozero | nonan)
628 ;
629 mshrAccesses[access_idx] =
630 mshr_hits[access_idx] + mshr_misses[access_idx]
631 + mshr_uncacheable[access_idx];
632 }
633
634 demandMshrAccesses
635 .name(name() + ".demand_mshr_accesses")
636 .desc("number of demand (read+write) mshr accesses")
637 .flags(total | nozero | nonan)
638 ;
639 demandMshrAccesses = demandMshrHits + demandMshrMisses;
640
641 overallMshrAccesses
642 .name(name() + ".overall_mshr_accesses")
643 .desc("number of overall (read+write) mshr accesses")
644 .flags(total | nozero | nonan)
645 ;
646 overallMshrAccesses = overallMshrHits + overallMshrMisses
647 + overallMshrUncacheable;
648#endif
649
650 // MSHR miss rate formulas
651 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
652 MemCmd cmd(access_idx);
653 const string &cstr = cmd.toString();
654
655 mshrMissRate[access_idx]
656 .name(name() + "." + cstr + "_mshr_miss_rate")
657 .desc("mshr miss rate for " + cstr + " accesses")
658 .flags(total | nozero | nonan)
659 ;
660 mshrMissRate[access_idx] =
661 mshr_misses[access_idx] / accesses[access_idx];
662
663 for (int i = 0; i < system->maxMasters(); i++) {
664 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
665 }
666 }
667
668 demandMshrMissRate
669 .name(name() + ".demand_mshr_miss_rate")
670 .desc("mshr miss rate for demand accesses")
671 .flags(total | nozero | nonan)
672 ;
673 demandMshrMissRate = demandMshrMisses / demandAccesses;
674 for (int i = 0; i < system->maxMasters(); i++) {
675 demandMshrMissRate.subname(i, system->getMasterName(i));
676 }
677
678 overallMshrMissRate
679 .name(name() + ".overall_mshr_miss_rate")
680 .desc("mshr miss rate for overall accesses")
681 .flags(total | nozero | nonan)
682 ;
683 overallMshrMissRate = overallMshrMisses / overallAccesses;
684 for (int i = 0; i < system->maxMasters(); i++) {
685 overallMshrMissRate.subname(i, system->getMasterName(i));
686 }
687
688 // mshrMiss latency formulas
689 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
690 MemCmd cmd(access_idx);
691 const string &cstr = cmd.toString();
692
693 avgMshrMissLatency[access_idx]
694 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
695 .desc("average " + cstr + " mshr miss latency")
696 .flags(total | nozero | nonan)
697 ;
698 avgMshrMissLatency[access_idx] =
699 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
700
701 for (int i = 0; i < system->maxMasters(); i++) {
604 }
605 }
606
607 overallMshrUncacheableLatency
608 .name(name() + ".overall_mshr_uncacheable_latency")
609 .desc("number of overall MSHR uncacheable cycles")
610 .flags(total | nozero | nonan)
611 ;
612 overallMshrUncacheableLatency =
613 SUM_DEMAND(mshr_uncacheable_lat) +
614 SUM_NON_DEMAND(mshr_uncacheable_lat);
615 for (int i = 0; i < system->maxMasters(); i++) {
616 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
617 }
618
619#if 0
620 // MSHR access formulas
621 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
622 MemCmd cmd(access_idx);
623 const string &cstr = cmd.toString();
624
625 mshrAccesses[access_idx]
626 .name(name() + "." + cstr + "_mshr_accesses")
627 .desc("number of " + cstr + " mshr accesses(hits+misses)")
628 .flags(total | nozero | nonan)
629 ;
630 mshrAccesses[access_idx] =
631 mshr_hits[access_idx] + mshr_misses[access_idx]
632 + mshr_uncacheable[access_idx];
633 }
634
635 demandMshrAccesses
636 .name(name() + ".demand_mshr_accesses")
637 .desc("number of demand (read+write) mshr accesses")
638 .flags(total | nozero | nonan)
639 ;
640 demandMshrAccesses = demandMshrHits + demandMshrMisses;
641
642 overallMshrAccesses
643 .name(name() + ".overall_mshr_accesses")
644 .desc("number of overall (read+write) mshr accesses")
645 .flags(total | nozero | nonan)
646 ;
647 overallMshrAccesses = overallMshrHits + overallMshrMisses
648 + overallMshrUncacheable;
649#endif
650
651 // MSHR miss rate formulas
652 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
653 MemCmd cmd(access_idx);
654 const string &cstr = cmd.toString();
655
656 mshrMissRate[access_idx]
657 .name(name() + "." + cstr + "_mshr_miss_rate")
658 .desc("mshr miss rate for " + cstr + " accesses")
659 .flags(total | nozero | nonan)
660 ;
661 mshrMissRate[access_idx] =
662 mshr_misses[access_idx] / accesses[access_idx];
663
664 for (int i = 0; i < system->maxMasters(); i++) {
665 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
666 }
667 }
668
669 demandMshrMissRate
670 .name(name() + ".demand_mshr_miss_rate")
671 .desc("mshr miss rate for demand accesses")
672 .flags(total | nozero | nonan)
673 ;
674 demandMshrMissRate = demandMshrMisses / demandAccesses;
675 for (int i = 0; i < system->maxMasters(); i++) {
676 demandMshrMissRate.subname(i, system->getMasterName(i));
677 }
678
679 overallMshrMissRate
680 .name(name() + ".overall_mshr_miss_rate")
681 .desc("mshr miss rate for overall accesses")
682 .flags(total | nozero | nonan)
683 ;
684 overallMshrMissRate = overallMshrMisses / overallAccesses;
685 for (int i = 0; i < system->maxMasters(); i++) {
686 overallMshrMissRate.subname(i, system->getMasterName(i));
687 }
688
689 // mshrMiss latency formulas
690 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
691 MemCmd cmd(access_idx);
692 const string &cstr = cmd.toString();
693
694 avgMshrMissLatency[access_idx]
695 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
696 .desc("average " + cstr + " mshr miss latency")
697 .flags(total | nozero | nonan)
698 ;
699 avgMshrMissLatency[access_idx] =
700 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
701
702 for (int i = 0; i < system->maxMasters(); i++) {
702 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
703 avgMshrMissLatency[access_idx].subname(
704 i, system->getMasterName(i));
703 }
704 }
705
706 demandAvgMshrMissLatency
707 .name(name() + ".demand_avg_mshr_miss_latency")
708 .desc("average overall mshr miss latency")
709 .flags(total | nozero | nonan)
710 ;
711 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
712 for (int i = 0; i < system->maxMasters(); i++) {
713 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
714 }
715
716 overallAvgMshrMissLatency
717 .name(name() + ".overall_avg_mshr_miss_latency")
718 .desc("average overall mshr miss latency")
719 .flags(total | nozero | nonan)
720 ;
721 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
722 for (int i = 0; i < system->maxMasters(); i++) {
723 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
724 }
725
726 // mshrUncacheable latency formulas
727 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
728 MemCmd cmd(access_idx);
729 const string &cstr = cmd.toString();
730
731 avgMshrUncacheableLatency[access_idx]
732 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
733 .desc("average " + cstr + " mshr uncacheable latency")
734 .flags(total | nozero | nonan)
735 ;
736 avgMshrUncacheableLatency[access_idx] =
737 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
738
739 for (int i = 0; i < system->maxMasters(); i++) {
705 }
706 }
707
708 demandAvgMshrMissLatency
709 .name(name() + ".demand_avg_mshr_miss_latency")
710 .desc("average overall mshr miss latency")
711 .flags(total | nozero | nonan)
712 ;
713 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
714 for (int i = 0; i < system->maxMasters(); i++) {
715 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
716 }
717
718 overallAvgMshrMissLatency
719 .name(name() + ".overall_avg_mshr_miss_latency")
720 .desc("average overall mshr miss latency")
721 .flags(total | nozero | nonan)
722 ;
723 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
724 for (int i = 0; i < system->maxMasters(); i++) {
725 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
726 }
727
728 // mshrUncacheable latency formulas
729 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
730 MemCmd cmd(access_idx);
731 const string &cstr = cmd.toString();
732
733 avgMshrUncacheableLatency[access_idx]
734 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
735 .desc("average " + cstr + " mshr uncacheable latency")
736 .flags(total | nozero | nonan)
737 ;
738 avgMshrUncacheableLatency[access_idx] =
739 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
740
741 for (int i = 0; i < system->maxMasters(); i++) {
740 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
742 avgMshrUncacheableLatency[access_idx].subname(
743 i, system->getMasterName(i));
741 }
742 }
743
744 overallAvgMshrUncacheableLatency
745 .name(name() + ".overall_avg_mshr_uncacheable_latency")
746 .desc("average overall mshr uncacheable latency")
747 .flags(total | nozero | nonan)
748 ;
744 }
745 }
746
747 overallAvgMshrUncacheableLatency
748 .name(name() + ".overall_avg_mshr_uncacheable_latency")
749 .desc("average overall mshr uncacheable latency")
750 .flags(total | nozero | nonan)
751 ;
749 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
752 overallAvgMshrUncacheableLatency =
753 overallMshrUncacheableLatency / overallMshrUncacheable;
750 for (int i = 0; i < system->maxMasters(); i++) {
751 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
752 }
753
754}
754 for (int i = 0; i < system->maxMasters(); i++) {
755 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
756 }
757
758}