base.cc (8736:2d8a57343fe3) base.cc (8786:8be24baf68b8)
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Erik Hallnor
29 */
30
31/**
32 * @file
33 * Definition of BaseCache functions.
34 */
35
36#include "cpu/base.hh"
37#include "cpu/smt.hh"
38#include "debug/Cache.hh"
39#include "mem/cache/base.hh"
40#include "mem/cache/mshr.hh"
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Erik Hallnor
29 */
30
31/**
32 * @file
33 * Definition of BaseCache functions.
34 */
35
36#include "cpu/base.hh"
37#include "cpu/smt.hh"
38#include "debug/Cache.hh"
39#include "mem/cache/base.hh"
40#include "mem/cache/mshr.hh"
41#include "sim/full_system.hh"
41
42using namespace std;
43
44BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
45 const std::string &_label)
46 : SimpleTimingPort(_name, _cache), cache(_cache),
42
43using namespace std;
44
45BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
46 const std::string &_label)
47 : SimpleTimingPort(_name, _cache), cache(_cache),
47 label(_label), blocked(false), mustSendRetry(false)
48 label(_label), otherPort(NULL),
49 blocked(false), mustSendRetry(false)
48{
49}
50
51
52BaseCache::BaseCache(const Params *p)
53 : MemObject(p),
54 mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
55 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
56 MSHRQueue_WriteBuffer),
57 blkSize(p->block_size),
58 hitLatency(p->latency),
59 numTarget(p->tgts_per_mshr),
60 forwardSnoops(p->forward_snoops),
61 isTopLevel(p->is_top_level),
62 blocked(0),
63 noTargetMSHR(NULL),
64 missCount(p->max_miss_count),
65 drainEvent(NULL),
66 addrRange(p->addr_range),
67 _numCpus(p->num_cpus)
68{
69}
70
50{
51}
52
53
54BaseCache::BaseCache(const Params *p)
55 : MemObject(p),
56 mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
57 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
58 MSHRQueue_WriteBuffer),
59 blkSize(p->block_size),
60 hitLatency(p->latency),
61 numTarget(p->tgts_per_mshr),
62 forwardSnoops(p->forward_snoops),
63 isTopLevel(p->is_top_level),
64 blocked(0),
65 noTargetMSHR(NULL),
66 missCount(p->max_miss_count),
67 drainEvent(NULL),
68 addrRange(p->addr_range),
69 _numCpus(p->num_cpus)
70{
71}
72
73void
74BaseCache::CachePort::recvStatusChange(Port::Status status)
75{
76 if (status == Port::RangeChange) {
77 otherPort->sendStatusChange(Port::RangeChange);
78 }
79}
71
80
81
72bool
73BaseCache::CachePort::checkFunctional(PacketPtr pkt)
74{
75 pkt->pushLabel(label);
76 bool done = SimpleTimingPort::checkFunctional(pkt);
77 pkt->popLabel();
78 return done;
79}
80
81
82unsigned
83BaseCache::CachePort::deviceBlockSize() const
84{
85 return cache->getBlockSize();
86}
87
88
89bool
90BaseCache::CachePort::recvRetryCommon()
91{
92 assert(waitingOnRetry);
93 waitingOnRetry = false;
94 return false;
95}
96
97
98void
99BaseCache::CachePort::setBlocked()
100{
101 assert(!blocked);
102 DPRINTF(Cache, "Cache Blocking\n");
103 blocked = true;
104 //Clear the retry flag
105 mustSendRetry = false;
106}
107
108void
109BaseCache::CachePort::clearBlocked()
110{
111 assert(blocked);
112 DPRINTF(Cache, "Cache Unblocking\n");
113 blocked = false;
114 if (mustSendRetry)
115 {
116 DPRINTF(Cache, "Cache Sending Retry\n");
117 mustSendRetry = false;
118 SendRetryEvent *ev = new SendRetryEvent(this, true);
119 // @TODO: need to find a better time (next bus cycle?)
82bool
83BaseCache::CachePort::checkFunctional(PacketPtr pkt)
84{
85 pkt->pushLabel(label);
86 bool done = SimpleTimingPort::checkFunctional(pkt);
87 pkt->popLabel();
88 return done;
89}
90
91
92unsigned
93BaseCache::CachePort::deviceBlockSize() const
94{
95 return cache->getBlockSize();
96}
97
98
99bool
100BaseCache::CachePort::recvRetryCommon()
101{
102 assert(waitingOnRetry);
103 waitingOnRetry = false;
104 return false;
105}
106
107
108void
109BaseCache::CachePort::setBlocked()
110{
111 assert(!blocked);
112 DPRINTF(Cache, "Cache Blocking\n");
113 blocked = true;
114 //Clear the retry flag
115 mustSendRetry = false;
116}
117
118void
119BaseCache::CachePort::clearBlocked()
120{
121 assert(blocked);
122 DPRINTF(Cache, "Cache Unblocking\n");
123 blocked = false;
124 if (mustSendRetry)
125 {
126 DPRINTF(Cache, "Cache Sending Retry\n");
127 mustSendRetry = false;
128 SendRetryEvent *ev = new SendRetryEvent(this, true);
129 // @TODO: need to find a better time (next bus cycle?)
120 cache->schedule(ev, curTick() + 1);
130 schedule(ev, curTick() + 1);
121 }
122}
123
124
125void
126BaseCache::init()
127{
128 if (!cpuSidePort || !memSidePort)
129 panic("Cache not hooked up on both sides\n");
131 }
132}
133
134
135void
136BaseCache::init()
137{
138 if (!cpuSidePort || !memSidePort)
139 panic("Cache not hooked up on both sides\n");
130 cpuSidePort->sendRangeChange();
140 cpuSidePort->sendStatusChange(Port::RangeChange);
131}
132
133
134void
135BaseCache::regStats()
136{
137 using namespace Stats;
138
139 // Hit statistics
140 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
141 MemCmd cmd(access_idx);
142 const string &cstr = cmd.toString();
143
144 hits[access_idx]
141}
142
143
144void
145BaseCache::regStats()
146{
147 using namespace Stats;
148
149 // Hit statistics
150 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
151 MemCmd cmd(access_idx);
152 const string &cstr = cmd.toString();
153
154 hits[access_idx]
145#if FULL_SYSTEM
146 .init(_numCpus + 1)
147#else
148 .init(_numCpus)
149#endif
155 .init(FullSystem ? (_numCpus + 1) : _numCpus)
150 .name(name() + "." + cstr + "_hits")
151 .desc("number of " + cstr + " hits")
152 .flags(total | nozero | nonan)
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)
170 ;
171 demandHits = SUM_DEMAND(hits);
172
173 overallHits
174 .name(name() + ".overall_hits")
175 .desc("number of overall hits")
176 .flags(total)
177 ;
178 overallHits = demandHits + SUM_NON_DEMAND(hits);
179
180 // Miss statistics
181 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
182 MemCmd cmd(access_idx);
183 const string &cstr = cmd.toString();
184
185 misses[access_idx]
156 .name(name() + "." + cstr + "_hits")
157 .desc("number of " + cstr + " hits")
158 .flags(total | nozero | nonan)
159 ;
160 }
161
162// These macros make it easier to sum the right subset of commands and
163// to change the subset of commands that are considered "demand" vs
164// "non-demand"
165#define SUM_DEMAND(s) \
166 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
167
168// should writebacks be included here? prior code was inconsistent...
169#define SUM_NON_DEMAND(s) \
170 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
171
172 demandHits
173 .name(name() + ".demand_hits")
174 .desc("number of demand (read+write) hits")
175 .flags(total)
176 ;
177 demandHits = SUM_DEMAND(hits);
178
179 overallHits
180 .name(name() + ".overall_hits")
181 .desc("number of overall hits")
182 .flags(total)
183 ;
184 overallHits = demandHits + SUM_NON_DEMAND(hits);
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]
186#if FULL_SYSTEM
187 .init(_numCpus + 1)
188#else
189 .init(_numCpus)
190#endif
192 .init(FullSystem ? (_numCpus + 1) : _numCpus)
191 .name(name() + "." + cstr + "_misses")
192 .desc("number of " + cstr + " misses")
193 .flags(total | nozero | nonan)
194 ;
195 }
196
197 demandMisses
198 .name(name() + ".demand_misses")
199 .desc("number of demand (read+write) misses")
200 .flags(total)
201 ;
202 demandMisses = SUM_DEMAND(misses);
203
204 overallMisses
205 .name(name() + ".overall_misses")
206 .desc("number of overall misses")
207 .flags(total)
208 ;
209 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
210
211 // Miss latency statistics
212 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
213 MemCmd cmd(access_idx);
214 const string &cstr = cmd.toString();
215
216 missLatency[access_idx]
217 .init(maxThreadsPerCPU)
218 .name(name() + "." + cstr + "_miss_latency")
219 .desc("number of " + cstr + " miss cycles")
220 .flags(total | nozero | nonan)
221 ;
222 }
223
224 demandMissLatency
225 .name(name() + ".demand_miss_latency")
226 .desc("number of demand (read+write) miss cycles")
227 .flags(total)
228 ;
229 demandMissLatency = SUM_DEMAND(missLatency);
230
231 overallMissLatency
232 .name(name() + ".overall_miss_latency")
233 .desc("number of overall miss cycles")
234 .flags(total)
235 ;
236 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
237
238 // access formulas
239 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
240 MemCmd cmd(access_idx);
241 const string &cstr = cmd.toString();
242
243 accesses[access_idx]
244 .name(name() + "." + cstr + "_accesses")
245 .desc("number of " + cstr + " accesses(hits+misses)")
246 .flags(total | nozero | nonan)
247 ;
248
249 accesses[access_idx] = hits[access_idx] + misses[access_idx];
250 }
251
252 demandAccesses
253 .name(name() + ".demand_accesses")
254 .desc("number of demand (read+write) accesses")
255 .flags(total)
256 ;
257 demandAccesses = demandHits + demandMisses;
258
259 overallAccesses
260 .name(name() + ".overall_accesses")
261 .desc("number of overall (read+write) accesses")
262 .flags(total)
263 ;
264 overallAccesses = overallHits + overallMisses;
265
266 // miss rate formulas
267 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
268 MemCmd cmd(access_idx);
269 const string &cstr = cmd.toString();
270
271 missRate[access_idx]
272 .name(name() + "." + cstr + "_miss_rate")
273 .desc("miss rate for " + cstr + " accesses")
274 .flags(total | nozero | nonan)
275 ;
276
277 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
278 }
279
280 demandMissRate
281 .name(name() + ".demand_miss_rate")
282 .desc("miss rate for demand accesses")
283 .flags(total)
284 ;
285 demandMissRate = demandMisses / demandAccesses;
286
287 overallMissRate
288 .name(name() + ".overall_miss_rate")
289 .desc("miss rate for overall accesses")
290 .flags(total)
291 ;
292 overallMissRate = overallMisses / overallAccesses;
293
294 // miss latency formulas
295 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
296 MemCmd cmd(access_idx);
297 const string &cstr = cmd.toString();
298
299 avgMissLatency[access_idx]
300 .name(name() + "." + cstr + "_avg_miss_latency")
301 .desc("average " + cstr + " miss latency")
302 .flags(total | nozero | nonan)
303 ;
304
305 avgMissLatency[access_idx] =
306 missLatency[access_idx] / misses[access_idx];
307 }
308
309 demandAvgMissLatency
310 .name(name() + ".demand_avg_miss_latency")
311 .desc("average overall miss latency")
312 .flags(total)
313 ;
314 demandAvgMissLatency = demandMissLatency / demandMisses;
315
316 overallAvgMissLatency
317 .name(name() + ".overall_avg_miss_latency")
318 .desc("average overall miss latency")
319 .flags(total)
320 ;
321 overallAvgMissLatency = overallMissLatency / overallMisses;
322
323 blocked_cycles.init(NUM_BLOCKED_CAUSES);
324 blocked_cycles
325 .name(name() + ".blocked_cycles")
326 .desc("number of cycles access was blocked")
327 .subname(Blocked_NoMSHRs, "no_mshrs")
328 .subname(Blocked_NoTargets, "no_targets")
329 ;
330
331
332 blocked_causes.init(NUM_BLOCKED_CAUSES);
333 blocked_causes
334 .name(name() + ".blocked")
335 .desc("number of cycles access was blocked")
336 .subname(Blocked_NoMSHRs, "no_mshrs")
337 .subname(Blocked_NoTargets, "no_targets")
338 ;
339
340 avg_blocked
341 .name(name() + ".avg_blocked_cycles")
342 .desc("average number of cycles each access was blocked")
343 .subname(Blocked_NoMSHRs, "no_mshrs")
344 .subname(Blocked_NoTargets, "no_targets")
345 ;
346
347 avg_blocked = blocked_cycles / blocked_causes;
348
349 fastWrites
350 .name(name() + ".fast_writes")
351 .desc("number of fast writes performed")
352 ;
353
354 cacheCopies
355 .name(name() + ".cache_copies")
356 .desc("number of cache copies performed")
357 ;
358
359 writebacks
360 .init(maxThreadsPerCPU)
361 .name(name() + ".writebacks")
362 .desc("number of writebacks")
363 .flags(total)
364 ;
365
366 // MSHR statistics
367 // MSHR hit statistics
368 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
369 MemCmd cmd(access_idx);
370 const string &cstr = cmd.toString();
371
372 mshr_hits[access_idx]
373 .init(maxThreadsPerCPU)
374 .name(name() + "." + cstr + "_mshr_hits")
375 .desc("number of " + cstr + " MSHR hits")
376 .flags(total | nozero | nonan)
377 ;
378 }
379
380 demandMshrHits
381 .name(name() + ".demand_mshr_hits")
382 .desc("number of demand (read+write) MSHR hits")
383 .flags(total)
384 ;
385 demandMshrHits = SUM_DEMAND(mshr_hits);
386
387 overallMshrHits
388 .name(name() + ".overall_mshr_hits")
389 .desc("number of overall MSHR hits")
390 .flags(total)
391 ;
392 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
393
394 // MSHR miss statistics
395 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
396 MemCmd cmd(access_idx);
397 const string &cstr = cmd.toString();
398
399 mshr_misses[access_idx]
400 .init(maxThreadsPerCPU)
401 .name(name() + "." + cstr + "_mshr_misses")
402 .desc("number of " + cstr + " MSHR misses")
403 .flags(total | nozero | nonan)
404 ;
405 }
406
407 demandMshrMisses
408 .name(name() + ".demand_mshr_misses")
409 .desc("number of demand (read+write) MSHR misses")
410 .flags(total)
411 ;
412 demandMshrMisses = SUM_DEMAND(mshr_misses);
413
414 overallMshrMisses
415 .name(name() + ".overall_mshr_misses")
416 .desc("number of overall MSHR misses")
417 .flags(total)
418 ;
419 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
420
421 // MSHR miss latency statistics
422 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
423 MemCmd cmd(access_idx);
424 const string &cstr = cmd.toString();
425
426 mshr_miss_latency[access_idx]
427 .init(maxThreadsPerCPU)
428 .name(name() + "." + cstr + "_mshr_miss_latency")
429 .desc("number of " + cstr + " MSHR miss cycles")
430 .flags(total | nozero | nonan)
431 ;
432 }
433
434 demandMshrMissLatency
435 .name(name() + ".demand_mshr_miss_latency")
436 .desc("number of demand (read+write) MSHR miss cycles")
437 .flags(total)
438 ;
439 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
440
441 overallMshrMissLatency
442 .name(name() + ".overall_mshr_miss_latency")
443 .desc("number of overall MSHR miss cycles")
444 .flags(total)
445 ;
446 overallMshrMissLatency =
447 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
448
449 // MSHR uncacheable statistics
450 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
451 MemCmd cmd(access_idx);
452 const string &cstr = cmd.toString();
453
454 mshr_uncacheable[access_idx]
455 .init(maxThreadsPerCPU)
456 .name(name() + "." + cstr + "_mshr_uncacheable")
457 .desc("number of " + cstr + " MSHR uncacheable")
458 .flags(total | nozero | nonan)
459 ;
460 }
461
462 overallMshrUncacheable
463 .name(name() + ".overall_mshr_uncacheable_misses")
464 .desc("number of overall MSHR uncacheable misses")
465 .flags(total)
466 ;
467 overallMshrUncacheable =
468 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
469
470 // MSHR miss latency 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_uncacheable_lat[access_idx]
476 .init(maxThreadsPerCPU)
477 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
478 .desc("number of " + cstr + " MSHR uncacheable cycles")
479 .flags(total | nozero | nonan)
480 ;
481 }
482
483 overallMshrUncacheableLatency
484 .name(name() + ".overall_mshr_uncacheable_latency")
485 .desc("number of overall MSHR uncacheable cycles")
486 .flags(total)
487 ;
488 overallMshrUncacheableLatency =
489 SUM_DEMAND(mshr_uncacheable_lat) +
490 SUM_NON_DEMAND(mshr_uncacheable_lat);
491
492#if 0
493 // MSHR access formulas
494 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
495 MemCmd cmd(access_idx);
496 const string &cstr = cmd.toString();
497
498 mshrAccesses[access_idx]
499 .name(name() + "." + cstr + "_mshr_accesses")
500 .desc("number of " + cstr + " mshr accesses(hits+misses)")
501 .flags(total | nozero | nonan)
502 ;
503 mshrAccesses[access_idx] =
504 mshr_hits[access_idx] + mshr_misses[access_idx]
505 + mshr_uncacheable[access_idx];
506 }
507
508 demandMshrAccesses
509 .name(name() + ".demand_mshr_accesses")
510 .desc("number of demand (read+write) mshr accesses")
511 .flags(total | nozero | nonan)
512 ;
513 demandMshrAccesses = demandMshrHits + demandMshrMisses;
514
515 overallMshrAccesses
516 .name(name() + ".overall_mshr_accesses")
517 .desc("number of overall (read+write) mshr accesses")
518 .flags(total | nozero | nonan)
519 ;
520 overallMshrAccesses = overallMshrHits + overallMshrMisses
521 + overallMshrUncacheable;
522#endif
523
524 // MSHR miss rate formulas
525 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
526 MemCmd cmd(access_idx);
527 const string &cstr = cmd.toString();
528
529 mshrMissRate[access_idx]
530 .name(name() + "." + cstr + "_mshr_miss_rate")
531 .desc("mshr miss rate for " + cstr + " accesses")
532 .flags(total | nozero | nonan)
533 ;
534
535 mshrMissRate[access_idx] =
536 mshr_misses[access_idx] / accesses[access_idx];
537 }
538
539 demandMshrMissRate
540 .name(name() + ".demand_mshr_miss_rate")
541 .desc("mshr miss rate for demand accesses")
542 .flags(total)
543 ;
544 demandMshrMissRate = demandMshrMisses / demandAccesses;
545
546 overallMshrMissRate
547 .name(name() + ".overall_mshr_miss_rate")
548 .desc("mshr miss rate for overall accesses")
549 .flags(total)
550 ;
551 overallMshrMissRate = overallMshrMisses / overallAccesses;
552
553 // mshrMiss latency formulas
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 avgMshrMissLatency[access_idx]
559 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
560 .desc("average " + cstr + " mshr miss latency")
561 .flags(total | nozero | nonan)
562 ;
563
564 avgMshrMissLatency[access_idx] =
565 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
566 }
567
568 demandAvgMshrMissLatency
569 .name(name() + ".demand_avg_mshr_miss_latency")
570 .desc("average overall mshr miss latency")
571 .flags(total)
572 ;
573 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
574
575 overallAvgMshrMissLatency
576 .name(name() + ".overall_avg_mshr_miss_latency")
577 .desc("average overall mshr miss latency")
578 .flags(total)
579 ;
580 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
581
582 // mshrUncacheable latency 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 avgMshrUncacheableLatency[access_idx]
588 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
589 .desc("average " + cstr + " mshr uncacheable latency")
590 .flags(total | nozero | nonan)
591 ;
592
593 avgMshrUncacheableLatency[access_idx] =
594 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
595 }
596
597 overallAvgMshrUncacheableLatency
598 .name(name() + ".overall_avg_mshr_uncacheable_latency")
599 .desc("average overall mshr uncacheable latency")
600 .flags(total)
601 ;
602 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
603
604 mshr_cap_events
605 .init(maxThreadsPerCPU)
606 .name(name() + ".mshr_cap_events")
607 .desc("number of times MSHR cap was activated")
608 .flags(total)
609 ;
610
611 //software prefetching stats
612 soft_prefetch_mshr_full
613 .init(maxThreadsPerCPU)
614 .name(name() + ".soft_prefetch_mshr_full")
615 .desc("number of mshr full events for SW prefetching instrutions")
616 .flags(total)
617 ;
618
619 mshr_no_allocate_misses
620 .name(name() +".no_allocate_misses")
621 .desc("Number of misses that were no-allocate")
622 ;
623
624}
625
626unsigned int
627BaseCache::drain(Event *de)
628{
629 int count = memSidePort->drain(de) + cpuSidePort->drain(de);
630
631 // Set status
632 if (count != 0) {
633 drainEvent = de;
634
635 changeState(SimObject::Draining);
636 return count;
637 }
638
639 changeState(SimObject::Drained);
640 return 0;
641}
193 .name(name() + "." + cstr + "_misses")
194 .desc("number of " + cstr + " misses")
195 .flags(total | nozero | nonan)
196 ;
197 }
198
199 demandMisses
200 .name(name() + ".demand_misses")
201 .desc("number of demand (read+write) misses")
202 .flags(total)
203 ;
204 demandMisses = SUM_DEMAND(misses);
205
206 overallMisses
207 .name(name() + ".overall_misses")
208 .desc("number of overall misses")
209 .flags(total)
210 ;
211 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
212
213 // Miss latency statistics
214 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
215 MemCmd cmd(access_idx);
216 const string &cstr = cmd.toString();
217
218 missLatency[access_idx]
219 .init(maxThreadsPerCPU)
220 .name(name() + "." + cstr + "_miss_latency")
221 .desc("number of " + cstr + " miss cycles")
222 .flags(total | nozero | nonan)
223 ;
224 }
225
226 demandMissLatency
227 .name(name() + ".demand_miss_latency")
228 .desc("number of demand (read+write) miss cycles")
229 .flags(total)
230 ;
231 demandMissLatency = SUM_DEMAND(missLatency);
232
233 overallMissLatency
234 .name(name() + ".overall_miss_latency")
235 .desc("number of overall miss cycles")
236 .flags(total)
237 ;
238 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
239
240 // access formulas
241 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
242 MemCmd cmd(access_idx);
243 const string &cstr = cmd.toString();
244
245 accesses[access_idx]
246 .name(name() + "." + cstr + "_accesses")
247 .desc("number of " + cstr + " accesses(hits+misses)")
248 .flags(total | nozero | nonan)
249 ;
250
251 accesses[access_idx] = hits[access_idx] + misses[access_idx];
252 }
253
254 demandAccesses
255 .name(name() + ".demand_accesses")
256 .desc("number of demand (read+write) accesses")
257 .flags(total)
258 ;
259 demandAccesses = demandHits + demandMisses;
260
261 overallAccesses
262 .name(name() + ".overall_accesses")
263 .desc("number of overall (read+write) accesses")
264 .flags(total)
265 ;
266 overallAccesses = overallHits + overallMisses;
267
268 // miss rate formulas
269 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
270 MemCmd cmd(access_idx);
271 const string &cstr = cmd.toString();
272
273 missRate[access_idx]
274 .name(name() + "." + cstr + "_miss_rate")
275 .desc("miss rate for " + cstr + " accesses")
276 .flags(total | nozero | nonan)
277 ;
278
279 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
280 }
281
282 demandMissRate
283 .name(name() + ".demand_miss_rate")
284 .desc("miss rate for demand accesses")
285 .flags(total)
286 ;
287 demandMissRate = demandMisses / demandAccesses;
288
289 overallMissRate
290 .name(name() + ".overall_miss_rate")
291 .desc("miss rate for overall accesses")
292 .flags(total)
293 ;
294 overallMissRate = overallMisses / overallAccesses;
295
296 // miss latency 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 avgMissLatency[access_idx]
302 .name(name() + "." + cstr + "_avg_miss_latency")
303 .desc("average " + cstr + " miss latency")
304 .flags(total | nozero | nonan)
305 ;
306
307 avgMissLatency[access_idx] =
308 missLatency[access_idx] / misses[access_idx];
309 }
310
311 demandAvgMissLatency
312 .name(name() + ".demand_avg_miss_latency")
313 .desc("average overall miss latency")
314 .flags(total)
315 ;
316 demandAvgMissLatency = demandMissLatency / demandMisses;
317
318 overallAvgMissLatency
319 .name(name() + ".overall_avg_miss_latency")
320 .desc("average overall miss latency")
321 .flags(total)
322 ;
323 overallAvgMissLatency = overallMissLatency / overallMisses;
324
325 blocked_cycles.init(NUM_BLOCKED_CAUSES);
326 blocked_cycles
327 .name(name() + ".blocked_cycles")
328 .desc("number of cycles access was blocked")
329 .subname(Blocked_NoMSHRs, "no_mshrs")
330 .subname(Blocked_NoTargets, "no_targets")
331 ;
332
333
334 blocked_causes.init(NUM_BLOCKED_CAUSES);
335 blocked_causes
336 .name(name() + ".blocked")
337 .desc("number of cycles access was blocked")
338 .subname(Blocked_NoMSHRs, "no_mshrs")
339 .subname(Blocked_NoTargets, "no_targets")
340 ;
341
342 avg_blocked
343 .name(name() + ".avg_blocked_cycles")
344 .desc("average number of cycles each access was blocked")
345 .subname(Blocked_NoMSHRs, "no_mshrs")
346 .subname(Blocked_NoTargets, "no_targets")
347 ;
348
349 avg_blocked = blocked_cycles / blocked_causes;
350
351 fastWrites
352 .name(name() + ".fast_writes")
353 .desc("number of fast writes performed")
354 ;
355
356 cacheCopies
357 .name(name() + ".cache_copies")
358 .desc("number of cache copies performed")
359 ;
360
361 writebacks
362 .init(maxThreadsPerCPU)
363 .name(name() + ".writebacks")
364 .desc("number of writebacks")
365 .flags(total)
366 ;
367
368 // MSHR statistics
369 // MSHR hit statistics
370 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
371 MemCmd cmd(access_idx);
372 const string &cstr = cmd.toString();
373
374 mshr_hits[access_idx]
375 .init(maxThreadsPerCPU)
376 .name(name() + "." + cstr + "_mshr_hits")
377 .desc("number of " + cstr + " MSHR hits")
378 .flags(total | nozero | nonan)
379 ;
380 }
381
382 demandMshrHits
383 .name(name() + ".demand_mshr_hits")
384 .desc("number of demand (read+write) MSHR hits")
385 .flags(total)
386 ;
387 demandMshrHits = SUM_DEMAND(mshr_hits);
388
389 overallMshrHits
390 .name(name() + ".overall_mshr_hits")
391 .desc("number of overall MSHR hits")
392 .flags(total)
393 ;
394 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
395
396 // MSHR miss statistics
397 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
398 MemCmd cmd(access_idx);
399 const string &cstr = cmd.toString();
400
401 mshr_misses[access_idx]
402 .init(maxThreadsPerCPU)
403 .name(name() + "." + cstr + "_mshr_misses")
404 .desc("number of " + cstr + " MSHR misses")
405 .flags(total | nozero | nonan)
406 ;
407 }
408
409 demandMshrMisses
410 .name(name() + ".demand_mshr_misses")
411 .desc("number of demand (read+write) MSHR misses")
412 .flags(total)
413 ;
414 demandMshrMisses = SUM_DEMAND(mshr_misses);
415
416 overallMshrMisses
417 .name(name() + ".overall_mshr_misses")
418 .desc("number of overall MSHR misses")
419 .flags(total)
420 ;
421 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
422
423 // MSHR miss latency statistics
424 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
425 MemCmd cmd(access_idx);
426 const string &cstr = cmd.toString();
427
428 mshr_miss_latency[access_idx]
429 .init(maxThreadsPerCPU)
430 .name(name() + "." + cstr + "_mshr_miss_latency")
431 .desc("number of " + cstr + " MSHR miss cycles")
432 .flags(total | nozero | nonan)
433 ;
434 }
435
436 demandMshrMissLatency
437 .name(name() + ".demand_mshr_miss_latency")
438 .desc("number of demand (read+write) MSHR miss cycles")
439 .flags(total)
440 ;
441 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
442
443 overallMshrMissLatency
444 .name(name() + ".overall_mshr_miss_latency")
445 .desc("number of overall MSHR miss cycles")
446 .flags(total)
447 ;
448 overallMshrMissLatency =
449 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
450
451 // MSHR uncacheable statistics
452 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
453 MemCmd cmd(access_idx);
454 const string &cstr = cmd.toString();
455
456 mshr_uncacheable[access_idx]
457 .init(maxThreadsPerCPU)
458 .name(name() + "." + cstr + "_mshr_uncacheable")
459 .desc("number of " + cstr + " MSHR uncacheable")
460 .flags(total | nozero | nonan)
461 ;
462 }
463
464 overallMshrUncacheable
465 .name(name() + ".overall_mshr_uncacheable_misses")
466 .desc("number of overall MSHR uncacheable misses")
467 .flags(total)
468 ;
469 overallMshrUncacheable =
470 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
471
472 // MSHR miss latency statistics
473 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
474 MemCmd cmd(access_idx);
475 const string &cstr = cmd.toString();
476
477 mshr_uncacheable_lat[access_idx]
478 .init(maxThreadsPerCPU)
479 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
480 .desc("number of " + cstr + " MSHR uncacheable cycles")
481 .flags(total | nozero | nonan)
482 ;
483 }
484
485 overallMshrUncacheableLatency
486 .name(name() + ".overall_mshr_uncacheable_latency")
487 .desc("number of overall MSHR uncacheable cycles")
488 .flags(total)
489 ;
490 overallMshrUncacheableLatency =
491 SUM_DEMAND(mshr_uncacheable_lat) +
492 SUM_NON_DEMAND(mshr_uncacheable_lat);
493
494#if 0
495 // MSHR access formulas
496 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
497 MemCmd cmd(access_idx);
498 const string &cstr = cmd.toString();
499
500 mshrAccesses[access_idx]
501 .name(name() + "." + cstr + "_mshr_accesses")
502 .desc("number of " + cstr + " mshr accesses(hits+misses)")
503 .flags(total | nozero | nonan)
504 ;
505 mshrAccesses[access_idx] =
506 mshr_hits[access_idx] + mshr_misses[access_idx]
507 + mshr_uncacheable[access_idx];
508 }
509
510 demandMshrAccesses
511 .name(name() + ".demand_mshr_accesses")
512 .desc("number of demand (read+write) mshr accesses")
513 .flags(total | nozero | nonan)
514 ;
515 demandMshrAccesses = demandMshrHits + demandMshrMisses;
516
517 overallMshrAccesses
518 .name(name() + ".overall_mshr_accesses")
519 .desc("number of overall (read+write) mshr accesses")
520 .flags(total | nozero | nonan)
521 ;
522 overallMshrAccesses = overallMshrHits + overallMshrMisses
523 + overallMshrUncacheable;
524#endif
525
526 // MSHR miss rate formulas
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 mshrMissRate[access_idx]
532 .name(name() + "." + cstr + "_mshr_miss_rate")
533 .desc("mshr miss rate for " + cstr + " accesses")
534 .flags(total | nozero | nonan)
535 ;
536
537 mshrMissRate[access_idx] =
538 mshr_misses[access_idx] / accesses[access_idx];
539 }
540
541 demandMshrMissRate
542 .name(name() + ".demand_mshr_miss_rate")
543 .desc("mshr miss rate for demand accesses")
544 .flags(total)
545 ;
546 demandMshrMissRate = demandMshrMisses / demandAccesses;
547
548 overallMshrMissRate
549 .name(name() + ".overall_mshr_miss_rate")
550 .desc("mshr miss rate for overall accesses")
551 .flags(total)
552 ;
553 overallMshrMissRate = overallMshrMisses / overallAccesses;
554
555 // mshrMiss latency formulas
556 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
557 MemCmd cmd(access_idx);
558 const string &cstr = cmd.toString();
559
560 avgMshrMissLatency[access_idx]
561 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
562 .desc("average " + cstr + " mshr miss latency")
563 .flags(total | nozero | nonan)
564 ;
565
566 avgMshrMissLatency[access_idx] =
567 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
568 }
569
570 demandAvgMshrMissLatency
571 .name(name() + ".demand_avg_mshr_miss_latency")
572 .desc("average overall mshr miss latency")
573 .flags(total)
574 ;
575 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
576
577 overallAvgMshrMissLatency
578 .name(name() + ".overall_avg_mshr_miss_latency")
579 .desc("average overall mshr miss latency")
580 .flags(total)
581 ;
582 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
583
584 // mshrUncacheable latency formulas
585 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
586 MemCmd cmd(access_idx);
587 const string &cstr = cmd.toString();
588
589 avgMshrUncacheableLatency[access_idx]
590 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
591 .desc("average " + cstr + " mshr uncacheable latency")
592 .flags(total | nozero | nonan)
593 ;
594
595 avgMshrUncacheableLatency[access_idx] =
596 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
597 }
598
599 overallAvgMshrUncacheableLatency
600 .name(name() + ".overall_avg_mshr_uncacheable_latency")
601 .desc("average overall mshr uncacheable latency")
602 .flags(total)
603 ;
604 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
605
606 mshr_cap_events
607 .init(maxThreadsPerCPU)
608 .name(name() + ".mshr_cap_events")
609 .desc("number of times MSHR cap was activated")
610 .flags(total)
611 ;
612
613 //software prefetching stats
614 soft_prefetch_mshr_full
615 .init(maxThreadsPerCPU)
616 .name(name() + ".soft_prefetch_mshr_full")
617 .desc("number of mshr full events for SW prefetching instrutions")
618 .flags(total)
619 ;
620
621 mshr_no_allocate_misses
622 .name(name() +".no_allocate_misses")
623 .desc("Number of misses that were no-allocate")
624 ;
625
626}
627
628unsigned int
629BaseCache::drain(Event *de)
630{
631 int count = memSidePort->drain(de) + cpuSidePort->drain(de);
632
633 // Set status
634 if (count != 0) {
635 drainEvent = de;
636
637 changeState(SimObject::Draining);
638 return count;
639 }
640
641 changeState(SimObject::Drained);
642 return 0;
643}