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
bool m_verbose
Verbose mode flag.
EventId m_event
The next progress event.
void DefaultTimePrinter(std::ostream &os)
Default Time printer.
Definition: time-printer.cc:39
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
ShowProgress(const Time interval=Seconds(1.0), std::ostream &os=std::cout)
Constructor.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
~ShowProgress(void)
Destructor.
ns3::ShowProgress declaration.
SystemWallClockMs m_timer
Wallclock timer.
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:45
Time m_interval
The target update interval, in wallclock time.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
void ScheduleCheckProgress(void)
Schedule the next CheckProgress.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event&#39;s associated function will not be invoked when it expires...
Definition: simulator.cc:268
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:802
ns3::Simulator declaration.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
void Stop(void)
Stop the elapsed wallclock timestamp and print the total elapsed time.
void SetVerbose(bool verbose)
Set verbose mode to print real and virtual time intervals.
void SetStream(std::ostream &os)
Set the output stream to show progress on.
void GiveFeedback(uint64_t nEvents, int64x64_t ratio, int64x64_t speed)
Show execution progress.
std::ostream * m_os
The output stream to use.
static const int64x64_t MAXGAIN
Maximum growth factor.
Time m_elapsed
Total elapsed wallclock time since last update.
static const int64x64_t HYSTERESIS
Hysteresis factor.
void Start(void)
Start a measure.
void SetInterval(const Time interval)
Set the target update interval, in wallclock time.
Declaration of classes ns3::Time and ns3::TimeWithUnit, and the TimeValue implementation classes...
SystemWallClockTimestamp m_stamp
Elapsed wallclock time.
uint64_t m_eventCount
Simulator event count.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
void(* TimePrinter)(std::ostream &os)
Function signature for features requiring a time formatter, such as logging or ShowProgress.
Definition: time-printer.h:43
double f(double x, void *params)
Definition: 80211b.c:70
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void Start(void)
Start the elapsed wallclock timestamp and print the start time.
void SetTimePrinter(TimePrinter lp)
Set the TimePrinter function to be used to prepend progress messages with the simulation time...
static uint64_t GetEventCount(void)
Get the number of events executed.
Definition: simulator.cc:306
void Stamp(void)
Record the current wall-clock time and delta since the last stamp().
std::time_t GetInterval(void) const
Get the last recorded interval.
TimePrinter m_printer
The TimePrinter to use.
Time m_vtime
The virtual time interval.
void CheckProgress(void)
Check on execution progress.
double GetDouble(void) const
Get this value as a double.
Definition: int64x64-128.h:206
std::string ToString(void) const
Get the last time stamp as a string.
second
Definition: nstime.h:115
uint64_t m_repCount
Number of CheckProgress events.
Debug message logging.
int64_t End(void)
Stop measuring the time since Start() was called.
ns3::EventId declarations.
bool verbose