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