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