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