X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsim%2Fstat_control.cc;h=6324b36ef9e56f54326c063cc538abd731523240;hb=abd33d6fd26bb69d3bf53ceb6c2dc8f90d893e34;hp=228c83898d447d223a79dd179acf29da6f154410;hpb=e94103397c58ffe05d4c5c7f536edabfb1d6861b;p=gem5.git diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc index 228c83898..6324b36ef 100644 --- a/src/sim/stat_control.cc +++ b/src/sim/stat_control.cc @@ -1,5 +1,19 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2013 Advanced Micro Devices, Inc. + * Copyright (c) 2013 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,11 +40,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Nathan Binkert + * Sascha Bischoff */ // This file will contain default statistics for the simulator that // don't really belong to a specific simulator object +#include "sim/stat_control.hh" + #include #include #include @@ -40,68 +57,94 @@ #include "base/statistics.hh" #include "base/time.hh" #include "cpu/base.hh" -#include "sim/eventq.hh" +#include "sim/global_event.hh" using namespace std; -Stats::Formula hostInstRate; -Stats::Formula hostTickRate; -Stats::Value hostMemory; -Stats::Value hostSeconds; - +Stats::Formula simSeconds; Stats::Value simTicks; -Stats::Value simInsts; +Stats::Value finalTick; Stats::Value simFreq; -Stats::Formula simSeconds; namespace Stats { Time statTime(true); Tick startTick; +GlobalEvent *dumpEvent; + struct SimTicksReset : public Callback { void process() { - statTime.set(); - startTick = curTick; + statTime.setTimer(); + startTick = curTick(); } }; double statElapsedTime() { - Time now(true); + Time now; + now.setTimer(); + Time elapsed = now - statTime; - return elapsed(); + return elapsed; } Tick statElapsedTicks() { - return curTick - startTick; + return curTick() - startTick; +} + +Tick +statFinalTick() +{ + return curTick(); } SimTicksReset simTicksReset; -void -initSimStats() +struct Global +{ + Stats::Formula hostInstRate; + Stats::Formula hostOpRate; + Stats::Formula hostTickRate; + Stats::Value hostMemory; + Stats::Value hostSeconds; + + Stats::Value simInsts; + Stats::Value simOps; + + Global(); +}; + +Global::Global() { simInsts - .functor(BaseCPU::numSimulatedInstructions) + .functor(BaseCPU::numSimulatedInsts) .name("sim_insts") .desc("Number of instructions simulated") .precision(0) .prereq(simInsts) ; + simOps + .functor(BaseCPU::numSimulatedOps) + .name("sim_ops") + .desc("Number of ops (including micro ops) simulated") + .precision(0) + .prereq(simOps) + ; + simSeconds .name("sim_seconds") .desc("Number of seconds simulated") ; simFreq - .scalar(Clock::Frequency) + .scalar(SimClock::Frequency) .name("sim_freq") .desc("Frequency of simulated ticks") ; @@ -112,6 +155,13 @@ initSimStats() .desc("Number of ticks simulated") ; + finalTick + .functor(statFinalTick) + .name("final_tick") + .desc("Number of ticks from beginning of simulation " + "(restored from checkpoints and never reset)") + ; + hostInstRate .name("host_inst_rate") .desc("Simulator instruction rate (inst/s)") @@ -119,6 +169,13 @@ initSimStats() .prereq(simInsts) ; + hostOpRate + .name("host_op_rate") + .desc("Simulator op (including micro ops) rate (op/s)") + .precision(0) + .prereq(simOps) + ; + hostMemory .functor(memUsage) .name("host_mem_usage") @@ -141,12 +198,22 @@ initSimStats() simSeconds = simTicks / simFreq; hostInstRate = simInsts / hostSeconds; + hostOpRate = simOps / hostSeconds; hostTickRate = simTicks / hostSeconds; registerResetCallback(&simTicksReset); } -class _StatEvent : public Event +void +initSimStats() +{ + static Global global; +} + +/** + * Event to dump and/or reset the statistics. + */ +class StatEvent : public GlobalEvent { private: bool dump; @@ -154,12 +221,10 @@ class _StatEvent : public Event Tick repeat; public: - _StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat) - : Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset), - repeat(_repeat) + StatEvent(Tick _when, bool _dump, bool _reset, Tick _repeat) + : GlobalEvent(_when, Stat_Event_Pri, 0), + dump(_dump), reset(_reset), repeat(_repeat) { - setFlags(AutoDelete); - schedule(_when); } virtual void @@ -171,15 +236,68 @@ class _StatEvent : public Event if (reset) Stats::reset(); - if (repeat) - new _StatEvent(dump, reset, curTick + repeat, repeat); + if (repeat) { + Stats::schedStatEvent(dump, reset, curTick() + repeat, repeat); + } } + + const char *description() const { return "GlobalStatEvent"; } }; void -StatEvent(bool dump, bool reset, Tick when, Tick repeat) +schedStatEvent(bool dump, bool reset, Tick when, Tick repeat) { - new _StatEvent(dump, reset, when, repeat); + // simQuantum is being added to the time when the stats would be + // dumped so as to ensure that this event happens only after the next + // sync amongst the event queues. Asingle event queue simulation + // should remain unaffected. + dumpEvent = new StatEvent(when + simQuantum, dump, reset, repeat); +} + +void +periodicStatDump(Tick period) +{ + /* + * If the period is set to 0, then we do not want to dump periodically, + * thus we deschedule the event. Else, if the period is not 0, but the event + * has already been scheduled, we need to get rid of the old event before we + * create a new one, as the old event will no longer be moved forward in the + * event that we resume from a checkpoint. + */ + if (dumpEvent != NULL && (period == 0 || dumpEvent->scheduled())) { + // Event should AutoDelete, so we do not need to free it. + dumpEvent->deschedule(); + } + + /* + * If the period is not 0, we schedule the event. If this is called with a + * period that is less than the current tick, then we shift the first dump + * by curTick. This ensures that we do not schedule the event is the past. + */ + if (period != 0) { + // Schedule the event + if (period >= curTick()) { + schedStatEvent(true, true, (Tick)period, (Tick)period); + } else { + schedStatEvent(true, true, (Tick)period + curTick(), (Tick)period); + } + } +} + +void +updateEvents() +{ + /* + * If the dumpEvent has been scheduled, but is scheduled in the past, then + * we need to shift the event to be at a valid point in time. Therefore, we + * shift the event by curTick. + */ + if (dumpEvent != NULL && + (dumpEvent->scheduled() && dumpEvent->when() < curTick())) { + // shift by curTick() and reschedule + Tick _when = dumpEvent->when(); + dumpEvent->reschedule(_when + curTick()); + } } -/* namespace Stats */ } +} // namespace Stats