base, sim, mem, arch: Remove the dummy CPU in NULL
[gem5.git] / src / sim / stat_control.cc
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) 2004-2005 The Regents of The University of Michigan
15 * Copyright (c) 2013 Advanced Micro Devices, Inc.
16 * Copyright (c) 2013 Mark D. Hill and David A. Wood
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
43 // This file will contain default statistics for the simulator that
44 // don't really belong to a specific simulator object
45
46 #include "sim/stat_control.hh"
47
48 #include <fstream>
49 #include <iostream>
50 #include <list>
51
52 #include "base/callback.hh"
53 #include "base/hostinfo.hh"
54 #include "base/statistics.hh"
55 #include "base/time.hh"
56 #include "config/the_isa.hh"
57 #if THE_ISA != NULL_ISA
58 #include "cpu/base.hh"
59 #endif
60 #include "sim/global_event.hh"
61
62 using namespace std;
63
64 Stats::Formula simSeconds;
65 Stats::Value simTicks;
66 Stats::Value finalTick;
67 Stats::Value simFreq;
68
69 namespace Stats {
70
71 Time statTime(true);
72 Tick startTick;
73
74 GlobalEvent *dumpEvent;
75
76 double
77 statElapsedTime()
78 {
79 Time now;
80 now.setTimer();
81
82 Time elapsed = now - statTime;
83 return elapsed;
84 }
85
86 Tick
87 statElapsedTicks()
88 {
89 return curTick() - startTick;
90 }
91
92 Tick
93 statFinalTick()
94 {
95 return curTick();
96 }
97
98 struct Global
99 {
100 Stats::Formula hostInstRate;
101 Stats::Formula hostOpRate;
102 Stats::Formula hostTickRate;
103 Stats::Value hostMemory;
104 Stats::Value hostSeconds;
105
106 Stats::Value simInsts;
107 Stats::Value simOps;
108
109 Global();
110 };
111
112 Global::Global()
113 {
114 simInsts
115 .name("sim_insts")
116 .desc("Number of instructions simulated")
117 .precision(0)
118 .prereq(simInsts)
119 ;
120
121 simOps
122 .name("sim_ops")
123 .desc("Number of ops (including micro ops) simulated")
124 .precision(0)
125 .prereq(simOps)
126 ;
127
128 #if THE_ISA != NULL_ISA
129 simInsts.functor(BaseCPU::numSimulatedInsts);
130 simOps.functor(BaseCPU::numSimulatedOps);
131 #else
132 simInsts.functor([] { return 0; });
133 simOps.functor([] { return 0; });
134 #endif
135
136 simSeconds
137 .name("sim_seconds")
138 .desc("Number of seconds simulated")
139 ;
140
141 simFreq
142 .scalar(SimClock::Frequency)
143 .name("sim_freq")
144 .desc("Frequency of simulated ticks")
145 ;
146
147 simTicks
148 .functor(statElapsedTicks)
149 .name("sim_ticks")
150 .desc("Number of ticks simulated")
151 ;
152
153 finalTick
154 .functor(statFinalTick)
155 .name("final_tick")
156 .desc("Number of ticks from beginning of simulation "
157 "(restored from checkpoints and never reset)")
158 ;
159
160 hostInstRate
161 .name("host_inst_rate")
162 .desc("Simulator instruction rate (inst/s)")
163 .precision(0)
164 .prereq(simInsts)
165 ;
166
167 hostOpRate
168 .name("host_op_rate")
169 .desc("Simulator op (including micro ops) rate (op/s)")
170 .precision(0)
171 .prereq(simOps)
172 ;
173
174 hostMemory
175 .functor(memUsage)
176 .name("host_mem_usage")
177 .desc("Number of bytes of host memory used")
178 .prereq(hostMemory)
179 ;
180
181 hostSeconds
182 .functor(statElapsedTime)
183 .name("host_seconds")
184 .desc("Real time elapsed on the host")
185 .precision(2)
186 ;
187
188 hostTickRate
189 .name("host_tick_rate")
190 .desc("Simulator tick rate (ticks/s)")
191 .precision(0)
192 ;
193
194 simSeconds = simTicks / simFreq;
195 hostInstRate = simInsts / hostSeconds;
196 hostOpRate = simOps / hostSeconds;
197 hostTickRate = simTicks / hostSeconds;
198
199 registerResetCallback([]() {
200 statTime.setTimer();
201 startTick = curTick();
202 });
203 }
204
205 void
206 initSimStats()
207 {
208 static Global global;
209 }
210
211 /**
212 * Event to dump and/or reset the statistics.
213 */
214 class StatEvent : public GlobalEvent
215 {
216 private:
217 bool dump;
218 bool reset;
219 Tick repeat;
220
221 public:
222 StatEvent(Tick _when, bool _dump, bool _reset, Tick _repeat)
223 : GlobalEvent(_when, Stat_Event_Pri, 0),
224 dump(_dump), reset(_reset), repeat(_repeat)
225 {
226 }
227
228 virtual void
229 process()
230 {
231 if (dump)
232 Stats::dump();
233
234 if (reset)
235 Stats::reset();
236
237 if (repeat) {
238 Stats::schedStatEvent(dump, reset, curTick() + repeat, repeat);
239 }
240 }
241
242 const char *description() const { return "GlobalStatEvent"; }
243 };
244
245 void
246 schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
247 {
248 // simQuantum is being added to the time when the stats would be
249 // dumped so as to ensure that this event happens only after the next
250 // sync amongst the event queues. Asingle event queue simulation
251 // should remain unaffected.
252 dumpEvent = new StatEvent(when + simQuantum, dump, reset, repeat);
253 }
254
255 void
256 periodicStatDump(Tick period)
257 {
258 /*
259 * If the period is set to 0, then we do not want to dump periodically,
260 * thus we deschedule the event. Else, if the period is not 0, but the event
261 * has already been scheduled, we need to get rid of the old event before we
262 * create a new one, as the old event will no longer be moved forward in the
263 * event that we resume from a checkpoint.
264 */
265 if (dumpEvent != NULL && (period == 0 || dumpEvent->scheduled())) {
266 // Event should AutoDelete, so we do not need to free it.
267 dumpEvent->deschedule();
268 }
269
270 /*
271 * If the period is not 0, we schedule the event. If this is called with a
272 * period that is less than the current tick, then we shift the first dump
273 * by curTick. This ensures that we do not schedule the event is the past.
274 */
275 if (period != 0) {
276 // Schedule the event
277 if (period >= curTick()) {
278 schedStatEvent(true, true, (Tick)period, (Tick)period);
279 } else {
280 schedStatEvent(true, true, (Tick)period + curTick(), (Tick)period);
281 }
282 }
283 }
284
285 void
286 updateEvents()
287 {
288 /*
289 * If the dumpEvent has been scheduled, but is scheduled in the past, then
290 * we need to shift the event to be at a valid point in time. Therefore, we
291 * shift the event by curTick.
292 */
293 if (dumpEvent != NULL &&
294 (dumpEvent->scheduled() && dumpEvent->when() < curTick())) {
295 // shift by curTick() and reschedule
296 Tick _when = dumpEvent->when();
297 dumpEvent->reschedule(_when + curTick());
298 }
299 }
300
301 } // namespace Stats