A Discrete-Event Network Simulator
API
show-progress.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2017 Lawrence Livermore National Laboratory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Gustavo Carneiro <gjc@inescporto.pt>
19  * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
20  */
21 
28 #include "show-progress.h"
29 #include "event-id.h"
30 #include "log.h"
31 #include "nstime.h"
32 #include "simulator.h"
33 
34 #include <iomanip>
35 
36 
37 namespace ns3 {
38 
39 NS_LOG_COMPONENT_DEFINE ("ShowProgress");
40 
41 /* static */
42 const int64x64_t ShowProgress::HYSTERESIS = 1.414;
43 /* static */
44 const int64x64_t ShowProgress::MAXGAIN = 2.0;
45 
46 ShowProgress::ShowProgress (const Time interval /* = Seconds (1.0) */,
47  std::ostream & os /* = std::cout */)
48  : m_timer (),
49  m_stamp (),
50  m_elapsed (),
51  m_interval (interval),
52  m_vtime (Time (1)),
53  m_event (),
54  m_eventCount (0),
55  m_printer (DefaultTimePrinter),
56  m_os (&os),
57  m_verbose (false),
58  m_repCount (0)
59 {
60  NS_LOG_FUNCTION (this << interval);
62  Start ();
63 }
64 
65 
67 {
68  Stop ();
69 }
70 
71 
72 void
74 {
75  NS_LOG_FUNCTION (this << interval);
76  const int64x64_t ratio = interval / m_interval;
77  m_interval = interval;
78  // If we aren't at the initial value assume we have a reasonable
79  // update time m_vtime, so we should rescale it
80  if (m_vtime > Time (1))
81  {
82  m_vtime = m_vtime * ratio;
83  }
85  Start ();
86 
87 } // ShowProgress::SetInterval
88 
89 void
91 {
92  NS_LOG_FUNCTION (this << lp);
93  m_printer = lp;
94 }
95 
96 void
98 {
99  NS_LOG_FUNCTION (this << verbose);
100  m_verbose = verbose;
101 }
102 
103 void
104 ShowProgress::SetStream (std::ostream & os)
105 {
106  m_os = &os;
107 }
108 
109 void
111 {
112  NS_LOG_FUNCTION (this);
114  m_timer.Start ();
115 
116 } // ShowProgress::ScheduleCheckProgress
117 
118 void
119 ShowProgress::GiveFeedback (uint64_t nEvents, int64x64_t ratio, int64x64_t speed)
120 {
121  // Save stream state
122  auto precision = m_os->precision ();
123  auto flags = m_os->flags ();
124 
125  m_os->setf (std::ios::fixed, std:: ios::floatfield);
126 
127  if (m_verbose)
128  {
129  (*m_os) << std::right << std::setw (5) << m_repCount << std::left
130  << (ratio > (1.0 / HYSTERESIS) ? "-->" : " ")
131  << std::setprecision (9)
132  << " [del: " << m_elapsed.As (Time::S)
133  << "/ int: " << m_interval.As (Time::S)
134  << " = rat: " << ratio
135  << (ratio > HYSTERESIS ? " dn" :
136  (ratio < 1.0 / HYSTERESIS ? " up" : " --"))
137  << ", vt: " << m_vtime.As (Time::S) << "] ";
138  }
139 
140  // Print the current time
141  (*m_printer)(*m_os);
142 
143  (*m_os) << " ("
144  << std::setprecision (3) << std::setw (8) << speed.GetDouble () << "x real time) "
145  << nEvents << " events processed"
146  << std::endl
147  << std::flush;
148 
149  // Restore stream state
150  m_os->precision (precision);
151  m_os->flags (flags);
152 
153 } // ShowProgress::GiveFeedback
154 
155 void
157 {
158  // Get elapsed wall clock time
160  NS_LOG_FUNCTION (this << m_elapsed);
161 
162  // Don't do anything unless the elapsed time is positive.
163  if (m_elapsed <= Time (0))
164  {
165  m_vtime = m_vtime * MAXGAIN;
166  ++m_repCount;
168  return;
169  }
170 
171  // Speed: how fast are we compared to real time
172  const int64x64_t speed = m_vtime / m_elapsed;
173 
174  // Ratio: how much real time did we use,
175  // compared to reporting interval target
176  const int64x64_t ratio = m_elapsed / m_interval;
177 
178  // Elapsed event count
179  uint64_t events = Simulator::GetEventCount ();
180  uint64_t nEvents = events - m_eventCount;
239  if (ratio > HYSTERESIS)
240  {
241  int64x64_t f = 1 + (ratio - 1) / 2;
242  if (ratio > MAXGAIN)
243  {
244  f = MAXGAIN;
245  }
246 
247  m_vtime = m_vtime / f;
248  }
249  else if (ratio < 1.0 / HYSTERESIS)
250  {
251  int64x64_t f = 1 + (1 / ratio - 1)/2;
252  if (1 / ratio > MAXGAIN)
253  {
254  f = MAXGAIN;
255  }
256  m_vtime = m_vtime * f;
257  }
258 
259  // Only give feedback if ratio is at least as big as 1/HYSTERESIS
260  if (ratio > (1.0 / HYSTERESIS))
261  {
262  GiveFeedback (nEvents, ratio, speed);
263  m_elapsed = Time (0);
264  m_eventCount = events;
265  }
266  else
267  {
268  NS_LOG_LOGIC ("skipping update: " << ratio);
269  // enable this line for debugging, with --verbose
270  // GiveFeedback (nEvents, ratio, speed);
271  }
272  ++m_repCount;
273 
274  // And do it again
276 
277 } // ShowProgress::CheckProgress
278 
279 void
281 {
282  m_stamp.Stamp ();
283  (*m_os) << "Start wall clock: " << m_stamp.ToString ()
284  << std::endl;
285 } // ShowProgress::Start
286 
287 void
289 {
290  m_stamp.Stamp ();
291  (*m_os) << "End wall clock: " << m_stamp.ToString ()
292  << "\nElapsed wall clock: " << m_stamp.GetInterval () << "s"
293  << std::endl;
294 } // ShowProgress::Stop
295 
296 } // namespace ns3
double f(double x, void *params)
Definition: 80211b.c:70
bool m_verbose
Verbose mode flag.
void SetVerbose(bool verbose)
Set verbose mode to print real and virtual time intervals.
void Start(void)
Start the elapsed wallclock timestamp and print the start time.
std::ostream * m_os
The output stream to use.
void Stop(void)
Stop the elapsed wallclock timestamp and print the total elapsed time.
void SetTimePrinter(TimePrinter lp)
Set the TimePrinter function to be used to prepend progress messages with the simulation time.
ShowProgress(const Time interval=Seconds(1.0), std::ostream &os=std::cout)
Constructor.
Time m_interval
The target update interval, in wallclock time.
void CheckProgress(void)
Check on execution progress.
uint64_t m_repCount
Number of CheckProgress events.
void GiveFeedback(uint64_t nEvents, int64x64_t ratio, int64x64_t speed)
Show execution progress.
void SetStream(std::ostream &os)
Set the output stream to show progress on.
static const int64x64_t MAXGAIN
Maximum growth factor.
SystemWallClockTimestamp m_stamp
Elapsed wallclock time.
Time m_elapsed
Total elapsed wallclock time since last update.
Time m_vtime
The virtual time interval.
EventId m_event
The next progress event.
TimePrinter m_printer
The TimePrinter to use.
SystemWallClockMs m_timer
Wallclock timer.
void ScheduleCheckProgress(void)
Schedule the next CheckProgress.
~ShowProgress(void)
Destructor.
void SetInterval(const Time interval)
Set the target update interval, in wallclock time.
static const int64x64_t HYSTERESIS
Hysteresis factor.
uint64_t m_eventCount
Simulator event count.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static uint64_t GetEventCount(void)
Get the number of events executed.
Definition: simulator.cc:306
void Start(void)
Start a measure.
int64_t End(void)
Stop measuring the time since Start() was called.
std::string ToString(void) const
Get the last time stamp as a string.
std::time_t GetInterval(void) const
Get the last recorded interval.
void Stamp(void)
Record the current wall-clock time and delta since the last stamp().
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:56
double GetDouble(void) const
Get this value as a double.
Definition: int64x64-128.h:231
ns3::EventId declarations.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Debug message logging.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:793
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void(* TimePrinter)(std::ostream &os)
Function signature for features requiring a time formatter, such as logging or ShowProgress.
Definition: time-printer.h:43
void DefaultTimePrinter(std::ostream &os)
Default Time printer.
Definition: time-printer.cc:39
Declaration of classes ns3::Time and ns3::TimeWithUnit, and the TimeValue implementation classes.
bool verbose
ns3::ShowProgress declaration.
ns3::Simulator declaration.