A Discrete-Event Network Simulator
API
show-progress.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Lawrence Livermore National Laboratory
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Gustavo Carneiro <gjc@inescporto.pt>
18  * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
19  */
20 
27 #include "show-progress.h"
28 
29 #include "event-id.h"
30 #include "log.h"
31 #include "nstime.h"
32 #include "simulator.h"
33 
34 #include <iomanip>
35 
36 namespace ns3
37 {
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 
66 {
67  Stop();
68 }
69 
70 void
72 {
73  NS_LOG_FUNCTION(this << interval);
74  const int64x64_t ratio = interval / m_interval;
75  m_interval = interval;
76  // If we aren't at the initial value assume we have a reasonable
77  // update time m_vtime, so we should rescale it
78  if (m_vtime > Time(1))
79  {
80  m_vtime = m_vtime * ratio;
81  }
83  Start();
84 
85 } // ShowProgress::SetInterval
86 
87 void
89 {
90  NS_LOG_FUNCTION(this << lp);
91  m_printer = lp;
92 }
93 
94 void
96 {
97  NS_LOG_FUNCTION(this << verbose);
99 }
100 
101 void
102 ShowProgress::SetStream(std::ostream& os)
103 {
104  m_os = &os;
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION(this);
112  m_timer.Start();
113 
114 } // ShowProgress::ScheduleCheckProgress
115 
116 void
117 ShowProgress::GiveFeedback(uint64_t nEvents, int64x64_t ratio, int64x64_t speed)
118 {
119  // Save stream state
120  auto precision = m_os->precision();
121  auto flags = m_os->flags();
122 
123  m_os->setf(std::ios::fixed, std::ios::floatfield);
124 
125  if (m_verbose)
126  {
127  (*m_os) << std::right << std::setw(5) << m_repCount << std::left
128  << (ratio > (1.0 / HYSTERESIS) ? "-->" : " ") << std::setprecision(9)
129  << " [del: " << m_elapsed.As(Time::S) << "/ int: " << m_interval.As(Time::S)
130  << " = rat: " << ratio
131  << (ratio > HYSTERESIS ? " dn" : (ratio < 1.0 / HYSTERESIS ? " up" : " --"))
132  << ", vt: " << m_vtime.As(Time::S) << "] ";
133  }
134 
135  // Print the current time
136  (*m_printer)(*m_os);
137 
138  (*m_os) << " (" << std::setprecision(3) << std::setw(8) << speed.GetDouble() << "x real time) "
139  << nEvents << " events processed" << std::endl
140  << std::flush;
141 
142  // Restore stream state
143  m_os->precision(precision);
144  m_os->flags(flags);
145 
146 } // ShowProgress::GiveFeedback
147 
148 void
150 {
151  // Get elapsed wall clock time
153  NS_LOG_FUNCTION(this << m_elapsed);
154 
155  // Don't do anything unless the elapsed time is positive.
156  if (m_elapsed <= Time(0))
157  {
158  m_vtime = m_vtime * MAXGAIN;
159  ++m_repCount;
161  return;
162  }
163 
164  // Speed: how fast are we compared to real time
165  const int64x64_t speed = m_vtime / m_elapsed;
166 
167  // Ratio: how much real time did we use,
168  // compared to reporting interval target
169  const int64x64_t ratio = m_elapsed / m_interval;
170 
171  // Elapsed event count
172  uint64_t events = Simulator::GetEventCount();
173  uint64_t nEvents = events - m_eventCount;
232  if (ratio > HYSTERESIS)
233  {
234  int64x64_t f = 1 + (ratio - 1) / 2;
235  if (ratio > MAXGAIN)
236  {
237  f = MAXGAIN;
238  }
239 
240  m_vtime = m_vtime / f;
241  }
242  else if (ratio < 1.0 / HYSTERESIS)
243  {
244  int64x64_t f = 1 + (1 / ratio - 1) / 2;
245  if (1 / ratio > MAXGAIN)
246  {
247  f = MAXGAIN;
248  }
249  m_vtime = m_vtime * f;
250  }
251 
252  // Only give feedback if ratio is at least as big as 1/HYSTERESIS
253  if (ratio > (1.0 / HYSTERESIS))
254  {
255  GiveFeedback(nEvents, ratio, speed);
256  m_elapsed = Time(0);
257  m_eventCount = events;
258  }
259  else
260  {
261  NS_LOG_LOGIC("skipping update: " << ratio);
262  // enable this line for debugging, with --verbose
263  // GiveFeedback (nEvents, ratio, speed);
264  }
265  ++m_repCount;
266 
267  // And do it again
269 
270 } // ShowProgress::CheckProgress
271 
272 void
274 {
275  m_stamp.Stamp();
276  (*m_os) << "Start wall clock: " << m_stamp.ToString() << std::endl;
277 } // ShowProgress::Start
278 
279 void
281 {
282  m_stamp.Stamp();
283  (*m_os) << "End wall clock: " << m_stamp.ToString()
284  << "\nElapsed wall clock: " << m_stamp.GetInterval() << "s" << std::endl;
285 } // ShowProgress::Stop
286 
287 } // 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.
std::ostream * m_os
The output stream to use.
void Start()
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.
void Stop()
Stop the elapsed wallclock timestamp and print the total elapsed time.
ShowProgress(const Time interval=Seconds(1.0), std::ostream &os=std::cout)
Constructor.
Time m_interval
The target update interval, in wallclock time.
uint64_t m_repCount
Number of CheckProgress events.
~ShowProgress()
Destructor.
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.
void ScheduleCheckProgress()
Schedule the next CheckProgress.
EventId m_event
The next progress event.
void CheckProgress()
Check on execution progress.
TimePrinter m_printer
The TimePrinter to use.
SystemWallClockMs m_timer
Wallclock timer.
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 EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:285
static uint64_t GetEventCount()
Get the number of events executed.
Definition: simulator.cc:324
int64_t End()
Stop measuring the time since Start() was called.
void Start()
Start a measure.
std::time_t GetInterval() const
Get the last recorded interval.
std::string ToString() const
Get the last time stamp as a string.
void Stamp()
Record the current wall-clock time and delta since the last stamp().
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
High precision numerical type, implementing Q64.64 fixed precision.
double GetDouble() const
Get this value as a double.
ns3::EventId declarations.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:1338
Debug message logging.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:839
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:40
Declaration of classes ns3::Time and ns3::TimeWithUnit, and the TimeValue implementation classes.
bool verbose
ns3::ShowProgress declaration.
ns3::Simulator declaration.