crocoddyl  1.9.0
Contact RObot COntrol by Differential DYnamic programming Library (Crocoddyl)
stop-watch.cpp
1 // Copyright (c) 2010-2013 Tommaso Urli (tommaso.urli@uniud.it; University of Udine)
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 
24 #ifndef WIN32
25 #include <sys/time.h>
26 #else
27 #include <Windows.h>
28 #include <iomanip>
29 #endif
30 
31 #include <iomanip> // std::setprecision
32 #include "crocoddyl/core/utils/stop-watch.hpp"
33 
34 using std::map;
35 using std::ostringstream;
36 using std::string;
37 
38 namespace crocoddyl {
39 
40 Stopwatch& getProfiler() {
41  static Stopwatch s(REAL_TIME); // alternatives are CPU_TIME and REAL_TIME
42  return s;
43 }
44 
45 Stopwatch::Stopwatch(StopwatchMode _mode) : active(true), mode(_mode), profiler_active(false) {
46  records_of = new map<string, PerformanceData>();
47 }
48 
50 
52 
54 
56 
57 void Stopwatch::set_mode(StopwatchMode new_mode) { mode = new_mode; }
58 
59 bool Stopwatch::performance_exists(string perf_name) { return (records_of->find(perf_name) != records_of->end()); }
60 
61 long double Stopwatch::take_time() {
62  if (mode == CPU_TIME) {
63  // Use ctime
64  return clock();
65 
66  } else if (mode == REAL_TIME) {
67  // Query operating system
68 
69 #ifdef WIN32
70  /* In case of usage under Windows */
71  FILETIME ft;
72  LARGE_INTEGER intervals;
73 
74  // Get the amount of 100 nanoseconds intervals elapsed since January 1, 1601
75  // (UTC)
76  GetSystemTimeAsFileTime(&ft);
77  intervals.LowPart = ft.dwLowDateTime;
78  intervals.HighPart = ft.dwHighDateTime;
79 
80  long double measure = intervals.QuadPart;
81  measure -= 116444736000000000.0; // Convert to UNIX epoch time
82  measure /= 10000000.0; // Convert to seconds
83 
84  return measure;
85 #else
86  /* Linux, MacOS, ... */
87  struct timeval tv;
88  gettimeofday(&tv, NULL);
89 
90  long double measure = tv.tv_usec;
91  measure /= 1000000.0; // Convert to seconds
92  measure += tv.tv_sec; // Add seconds part
93 
94  return measure;
95 #endif
96 
97  } else {
98  // If mode == NONE, clock has not been initialized, then throw exception
99  throw StopwatchException("Clock not initialized to a time taking mode!");
100  }
101 }
102 
103 void Stopwatch::start(const string& perf_name) {
104  if (!active) return;
105 
106  // Just works if not already present
107  records_of->insert(make_pair(perf_name, PerformanceData()));
108 
109  PerformanceData& perf_info = records_of->find(perf_name)->second;
110 
111  // Take ctime
112  perf_info.clock_start = take_time();
113 
114  // If this is a new start (i.e. not a restart)
115  // if (!perf_info.paused)
116  // perf_info.last_time = 0;
117 
118  perf_info.paused = false;
119 }
120 
121 void Stopwatch::stop(const string& perf_name) {
122  if (!active) return;
123 
124  long double clock_end = take_time();
125 
126  // Try to recover performance data
127  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
128 
129  PerformanceData& perf_info = records_of->find(perf_name)->second;
130 
131  // check whether the performance has been reset
132  if (perf_info.clock_start == 0) return;
133 
134  perf_info.stops++;
135  long double lapse = clock_end - perf_info.clock_start;
136 
137  if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
138 
139  // Update last time
140  perf_info.last_time = lapse;
141 
142  // Update min/max time
143  if (lapse >= perf_info.max_time) perf_info.max_time = lapse;
144  if (lapse <= perf_info.min_time || perf_info.min_time == 0) perf_info.min_time = lapse;
145 
146  // Update total time
147  perf_info.total_time += lapse;
148 }
149 
150 void Stopwatch::pause(const string& perf_name) {
151  if (!active) return;
152 
153  long double clock_end = clock();
154 
155  // Try to recover performance data
156  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
157 
158  PerformanceData& perf_info = records_of->find(perf_name)->second;
159 
160  // check whether the performance has been reset
161  if (perf_info.clock_start == 0) return;
162 
163  long double lapse = clock_end - perf_info.clock_start;
164 
165  // Update total time
166  perf_info.last_time += lapse;
167  perf_info.total_time += lapse;
168 }
169 
171  if (!active) return;
172 
173  map<string, PerformanceData>::iterator it;
174 
175  for (it = records_of->begin(); it != records_of->end(); ++it) {
176  reset(it->first);
177  }
178 }
179 
180 void Stopwatch::report_all(int precision, std::ostream& output) {
181  if (!active) return;
182 
183  output << "\n" << std::setw(STOP_WATCH_MAX_NAME_LENGTH) << std::left << "*** PROFILING RESULTS [ms] ";
184  output << std::setw(STOP_WATCH_TIME_WIDTH) << "min"
185  << " ";
186  output << std::setw(STOP_WATCH_TIME_WIDTH) << "avg"
187  << " ";
188  output << std::setw(STOP_WATCH_TIME_WIDTH) << "max"
189  << " ";
190  output << std::setw(STOP_WATCH_TIME_WIDTH) << "lastTime"
191  << " ";
192  output << std::setw(STOP_WATCH_TIME_WIDTH) << "nSamples"
193  << " ";
194  output << std::setw(STOP_WATCH_TIME_WIDTH) << "totalTime"
195  << " ***\n";
196  map<string, PerformanceData>::iterator it;
197  for (it = records_of->begin(); it != records_of->end(); ++it) {
198  if (it->second.stops > 0) report(it->first, precision, output);
199  }
200 }
201 
202 void Stopwatch::reset(const string& perf_name) {
203  if (!active) return;
204 
205  // Try to recover performance data
206  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
207 
208  PerformanceData& perf_info = records_of->find(perf_name)->second;
209 
210  perf_info.clock_start = 0;
211  perf_info.total_time = 0;
212  perf_info.min_time = 0;
213  perf_info.max_time = 0;
214  perf_info.last_time = 0;
215  perf_info.paused = false;
216  perf_info.stops = 0;
217 }
218 
220  std::cout << "Stopwatch active." << std::endl;
221  active = true;
222 }
223 
225  std::cout << "Stopwatch inactive." << std::endl;
226  active = false;
227 }
228 
229 void Stopwatch::report(const string& perf_name, int precision, std::ostream& output) {
230  if (!active) return;
231 
232  // Try to recover performance data
233  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
234 
235  PerformanceData& perf_info = records_of->find(perf_name)->second;
236 
237  output << std::setw(STOP_WATCH_MAX_NAME_LENGTH) << std::left << perf_name;
238  output << std::fixed << std::setprecision(precision) << std::setw(STOP_WATCH_TIME_WIDTH)
239  << (perf_info.min_time * 1e3) << " ";
240  output << std::fixed << std::setprecision(precision) << std::setw(STOP_WATCH_TIME_WIDTH)
241  << (perf_info.total_time * 1e3 / (long double)perf_info.stops) << " ";
242  output << std::fixed << std::setprecision(precision) << std::setw(STOP_WATCH_TIME_WIDTH)
243  << (perf_info.max_time * 1e3) << " ";
244  output << std::fixed << std::setprecision(precision) << std::setw(STOP_WATCH_TIME_WIDTH)
245  << (perf_info.last_time * 1e3) << " ";
246  output << std::fixed << std::setprecision(precision) << std::setw(STOP_WATCH_TIME_WIDTH) << perf_info.stops << " ";
247  output << std::fixed << std::setprecision(precision) << std::setw(STOP_WATCH_TIME_WIDTH)
248  << perf_info.total_time * 1e3 << std::endl;
249 }
250 
251 long double Stopwatch::get_time_so_far(const string& perf_name) {
252  // Try to recover performance data
253  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
254 
255  long double lapse = (take_time() - (records_of->find(perf_name)->second).clock_start);
256 
257  if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
258 
259  return lapse;
260 }
261 
262 long double Stopwatch::get_total_time(const string& perf_name) {
263  // Try to recover performance data
264  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
265 
266  PerformanceData& perf_info = records_of->find(perf_name)->second;
267 
268  return perf_info.total_time;
269 }
270 
271 long double Stopwatch::get_average_time(const string& perf_name) {
272  // Try to recover performance data
273  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
274 
275  PerformanceData& perf_info = records_of->find(perf_name)->second;
276 
277  return (perf_info.total_time / (long double)perf_info.stops);
278 }
279 
280 long double Stopwatch::get_min_time(const string& perf_name) {
281  // Try to recover performance data
282  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
283 
284  PerformanceData& perf_info = records_of->find(perf_name)->second;
285 
286  return perf_info.min_time;
287 }
288 
289 long double Stopwatch::get_max_time(const string& perf_name) {
290  // Try to recover performance data
291  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
292 
293  PerformanceData& perf_info = records_of->find(perf_name)->second;
294 
295  return perf_info.max_time;
296 }
297 
298 long double Stopwatch::get_last_time(const string& perf_name) {
299  // Try to recover performance data
300  if (!performance_exists(perf_name)) throw StopwatchException("Performance not initialized.");
301 
302  PerformanceData& perf_info = records_of->find(perf_name)->second;
303 
304  return perf_info.last_time;
305 }
306 
307 } // end namespace crocoddyl
void start(const std::string &perf_name)
Start the stopwatch related to a certain piece of code.
Definition: stop-watch.cpp:103
void reset_all()
Resets all the performance records.
Definition: stop-watch.cpp:170
long double clock_start
Start time.
Definition: stop-watch.hpp:230
long double take_time()
Take time, depends on mode.
Definition: stop-watch.cpp:61
void reset(const std::string &perf_name)
Reset a certain performance record.
Definition: stop-watch.cpp:202
Struct to hold the performance data.
Definition: stop-watch.hpp:226
void turn_on()
Turn on clock, restore clock operativity after a turn_off().
Definition: stop-watch.cpp:219
void disable_profiler()
Disable the profiler.
Definition: stop-watch.cpp:53
~Stopwatch()
Destructor.
Definition: stop-watch.cpp:49
void report_all(int precision=2, std::ostream &output=std::cout)
Dump the data of all the performance records.
Definition: stop-watch.cpp:180
Stopwatch(StopwatchMode _mode=NONE)
Constructor.
Definition: stop-watch.cpp:45
long double get_min_time(const std::string &perf_name)
Returns minimum execution time of a certain performance.
Definition: stop-watch.cpp:280
int stops
How many cycles have been this stopwatch executed?
Definition: stop-watch.hpp:236
long double max_time
Maximum time.
Definition: stop-watch.hpp:233
long double get_total_time(const std::string &perf_name)
Returns total execution time of a certain performance.
Definition: stop-watch.cpp:262
bool profiler_active
Indicates if the profiler is enabled.
Definition: stop-watch.hpp:242
long double get_average_time(const std::string &perf_name)
Returns average execution time of a certain performance.
Definition: stop-watch.cpp:271
long double min_time
Minimum time.
Definition: stop-watch.hpp:232
bool performance_exists(std::string perf_name)
Tells if a performance with a certain ID exists.
Definition: stop-watch.cpp:59
long double last_time
Last time.
Definition: stop-watch.hpp:234
void enable_profiler()
Enable the profiler.
Definition: stop-watch.cpp:51
bool profiler_status()
Return if the profiler is enable or disable.
Definition: stop-watch.cpp:55
long double total_time
Cumulative total time.
Definition: stop-watch.hpp:231
StopwatchMode mode
Time taking mode.
Definition: stop-watch.hpp:240
void turn_off()
Turn off clock, all the Stopwatch::* methods return without doing anything after this method is calle...
Definition: stop-watch.cpp:224
long double get_time_so_far(const std::string &perf_name)
Return the time since the start of the last measurement of a given performance.
Definition: stop-watch.cpp:251
void set_mode(StopwatchMode mode)
Initialize stopwatch to use a certain time taking mode.
Definition: stop-watch.cpp:57
void stop(const std::string &perf_name)
Stops the stopwatch related to a certain piece of code.
Definition: stop-watch.cpp:121
void report(const std::string &perf_name, int precision=2, std::ostream &output=std::cout)
Dump the data of a certain performance record.
Definition: stop-watch.cpp:229
bool active
Flag to hold the clock&#39;s status.
Definition: stop-watch.hpp:239
std::map< std::string, PerformanceData > * records_of
Dynamic collection of performance data.
Definition: stop-watch.hpp:241
void pause(const std::string &perf_name)
Stops the stopwatch related to a certain piece of code.
Definition: stop-watch.cpp:150
long double get_max_time(const std::string &perf_name)
Returns maximum execution time of a certain performance.
Definition: stop-watch.cpp:289
bool paused
Tells if this performance has been paused, only for internal use.
Definition: stop-watch.hpp:235
long double get_last_time(const std::string &perf_name)
Return last measurement of a certain performance.
Definition: stop-watch.cpp:298