stat_control.cc revision 9850:87d6b41749e9
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 * 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: Nathan Binkert
41 *          Sascha Bischoff
42 */
43
44// This file will contain default statistics for the simulator that
45// don't really belong to a specific simulator object
46
47#include <fstream>
48#include <iostream>
49#include <list>
50
51#include "base/callback.hh"
52#include "base/hostinfo.hh"
53#include "base/statistics.hh"
54#include "base/time.hh"
55#include "cpu/base.hh"
56#include "sim/eventq_impl.hh"
57#include "sim/stat_control.hh"
58
59using namespace std;
60
61Stats::Formula simSeconds;
62Stats::Value simTicks;
63Stats::Value finalTick;
64Stats::Value simFreq;
65
66namespace Stats {
67
68Time statTime(true);
69Tick startTick;
70
71Event *dumpEvent;
72
73struct SimTicksReset : public Callback
74{
75    void process()
76    {
77        statTime.setTimer();
78        startTick = curTick();
79    }
80};
81
82double
83statElapsedTime()
84{
85    Time now;
86    now.setTimer();
87
88    Time elapsed = now - statTime;
89    return elapsed;
90}
91
92Tick
93statElapsedTicks()
94{
95    return curTick() - startTick;
96}
97
98Tick
99statFinalTick()
100{
101    return curTick();
102}
103
104SimTicksReset simTicksReset;
105
106struct Global
107{
108    Stats::Formula hostInstRate;
109    Stats::Formula hostOpRate;
110    Stats::Formula hostTickRate;
111    Stats::Value hostMemory;
112    Stats::Value hostSeconds;
113
114    Stats::Value simInsts;
115    Stats::Value simOps;
116
117    Global();
118};
119
120Global::Global()
121{
122    simInsts
123        .functor(BaseCPU::numSimulatedInsts)
124        .name("sim_insts")
125        .desc("Number of instructions simulated")
126        .precision(0)
127        .prereq(simInsts)
128        ;
129
130    simOps
131        .functor(BaseCPU::numSimulatedOps)
132        .name("sim_ops")
133        .desc("Number of ops (including micro ops) simulated")
134        .precision(0)
135        .prereq(simOps)
136        ;
137
138    simSeconds
139        .name("sim_seconds")
140        .desc("Number of seconds simulated")
141        ;
142
143    simFreq
144        .scalar(SimClock::Frequency)
145        .name("sim_freq")
146        .desc("Frequency of simulated ticks")
147        ;
148
149    simTicks
150        .functor(statElapsedTicks)
151        .name("sim_ticks")
152        .desc("Number of ticks simulated")
153        ;
154
155    finalTick
156        .functor(statFinalTick)
157        .name("final_tick")
158        .desc("Number of ticks from beginning of simulation \
159(restored from checkpoints and never reset)")
160        ;
161
162    hostInstRate
163        .name("host_inst_rate")
164        .desc("Simulator instruction rate (inst/s)")
165        .precision(0)
166        .prereq(simInsts)
167        ;
168
169    hostOpRate
170        .name("host_op_rate")
171        .desc("Simulator op (including micro ops) rate (op/s)")
172        .precision(0)
173        .prereq(simOps)
174        ;
175
176    hostMemory
177        .functor(memUsage)
178        .name("host_mem_usage")
179        .desc("Number of bytes of host memory used")
180        .prereq(hostMemory)
181        ;
182
183    hostSeconds
184        .functor(statElapsedTime)
185        .name("host_seconds")
186        .desc("Real time elapsed on the host")
187        .precision(2)
188        ;
189
190    hostTickRate
191        .name("host_tick_rate")
192        .desc("Simulator tick rate (ticks/s)")
193        .precision(0)
194        ;
195
196    simSeconds = simTicks / simFreq;
197    hostInstRate = simInsts / hostSeconds;
198    hostOpRate = simOps / hostSeconds;
199    hostTickRate = simTicks / hostSeconds;
200
201    registerResetCallback(&simTicksReset);
202}
203
204void
205initSimStats()
206{
207    static Global global;
208}
209
210/**
211 * Event to dump and/or reset the statistics.
212 */
213class StatEvent : public Event
214{
215  private:
216    bool dump;
217    bool reset;
218    Tick repeat;
219
220  public:
221    StatEvent(bool _dump, bool _reset, Tick _repeat)
222        : Event(Stat_Event_Pri, AutoDelete),
223          dump(_dump), reset(_reset), repeat(_repeat)
224    {
225    }
226
227    virtual void
228    process()
229    {
230        if (dump)
231            Stats::dump();
232
233        if (reset)
234            Stats::reset();
235
236        if (repeat) {
237            Stats::schedStatEvent(dump, reset, curTick() + repeat, repeat);
238        }
239    }
240};
241
242void
243schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
244{
245    dumpEvent = new StatEvent(dump, reset, repeat);
246    mainEventQueue.schedule(dumpEvent, when);
247}
248
249void
250periodicStatDump(Tick period)
251{
252    /*
253     * If the period is set to 0, then we do not want to dump periodically,
254     * thus we deschedule the event. Else, if the period is not 0, but the event
255     * has already been scheduled, we need to get rid of the old event before we
256     * create a new one, as the old event will no longer be moved forward in the
257     * event that we resume from a checkpoint.
258     */
259    if (dumpEvent != NULL && (period == 0 || dumpEvent->scheduled())) {
260        // Event should AutoDelete, so we do not need to free it.
261        mainEventQueue.deschedule(dumpEvent);
262    }
263
264    /*
265     * If the period is not 0, we schedule the event. If this is called with a
266     * period that is less than the current tick, then we shift the first dump
267     * by curTick. This ensures that we do not schedule the event is the past.
268     */
269    if (period != 0) {
270        // Schedule the event
271        if (period >= curTick()) {
272            schedStatEvent(true, true, (Tick)period, (Tick)period);
273        } else {
274            schedStatEvent(true, true, (Tick)period + curTick(), (Tick)period);
275        }
276    }
277}
278
279void
280updateEvents()
281{
282    /*
283     * If the dumpEvent has been scheduled, but is scheduled in the past, then
284     * we need to shift the event to be at a valid point in time. Therefore, we
285     * shift the event by curTick.
286     */
287    if (dumpEvent != NULL &&
288        (dumpEvent->scheduled() && dumpEvent->when() < curTick())) {
289        // shift by curTick() and reschedule
290        Tick _when = dumpEvent->when();
291        mainEventQueue.reschedule(dumpEvent, _when + curTick());
292    }
293}
294
295} // namespace Stats
296