GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/utils/stop-watch.cpp Lines: 37 132 28.0 %
Date: 2023-03-13 12:09:37 Branches: 19 208 9.1 %

Line Branch Exec Source
1
/*
2
Copyright (c) 2010-2013 Tommaso Urli
3
4
Tommaso Urli    tommaso.urli@uniud.it   University of Udine
5
6
Permission is hereby granted, free of charge, to any person obtaining
7
a copy of this software and associated documentation files (the
8
"Software"), to deal in the Software without restriction, including
9
without limitation the rights to use, copy, modify, merge, publish,
10
distribute, sublicense, and/or sell copies of the Software, and to
11
permit persons to whom the Software is furnished to do so, subject to
12
the following conditions:
13
14
The above copyright notice and this permission notice shall be
15
included in all copies or substantial portions of the Software.
16
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25
*/
26
27
#ifndef WIN32
28
#include <sys/time.h>
29
#else
30
#include <Windows.h>
31
32
#include <iomanip>
33
#endif
34
35
#include <iomanip>  // std::setprecision
36
37
#include "sot/core/stop-watch.hh"
38
39
using std::map;
40
using std::ostringstream;
41
using std::string;
42
43
//#define START_PROFILER(name) getProfiler().start(name)
44
//#define STOP_PROFILER(name) getProfiler().stop(name)
45
46
8
Stopwatch &getProfiler() {
47


8
  static Stopwatch s(REAL_TIME);  // alternatives are CPU_TIME and REAL_TIME
48
8
  return s;
49
}
50
51
2
Stopwatch::Stopwatch(StopwatchMode _mode) : active(true), mode(_mode) {
52
2
  records_of = new map<string, PerformanceData>();
53
2
}
54
55
2
Stopwatch::~Stopwatch() { delete records_of; }
56
57
void Stopwatch::set_mode(StopwatchMode new_mode) { mode = new_mode; }
58
59
4
bool Stopwatch::performance_exists(string perf_name) {
60
4
  return (records_of->find(perf_name) != records_of->end());
61
}
62
63
8
long double Stopwatch::take_time() {
64
8
  if (mode == CPU_TIME) {
65
    // Use ctime
66
    return clock();
67
68
8
  } else if (mode == REAL_TIME) {
69
    // Query operating system
70
71
#ifdef WIN32
72
    /* In case of usage under Windows */
73
    FILETIME ft;
74
    LARGE_INTEGER intervals;
75
76
    // Get the amount of 100 nanoseconds intervals elapsed since January 1, 1601
77
    // (UTC)
78
    GetSystemTimeAsFileTime(&ft);
79
    intervals.LowPart = ft.dwLowDateTime;
80
    intervals.HighPart = ft.dwHighDateTime;
81
82
    long double measure = intervals.QuadPart;
83
    measure -= 116444736000000000.0;  // Convert to UNIX epoch time
84
    measure /= 10000000.0;            // Convert to seconds
85
86
    return measure;
87
#else
88
    /* Linux, MacOS, ... */
89
    struct timeval tv;
90
8
    gettimeofday(&tv, NULL);
91
92
8
    long double measure = tv.tv_usec;
93
8
    measure /= 1000000.0;  // Convert to seconds
94
8
    measure += tv.tv_sec;  // Add seconds part
95
96
8
    return measure;
97
#endif
98
99
  } else {
100
    // If mode == NONE, clock has not been initialized, then throw exception
101
    throw StopwatchException("Clock not initialized to a time taking mode!");
102
  }
103
}
104
105
4
void Stopwatch::start(string perf_name) {
106
4
  if (!active) return;
107
108
  // Just works if not already present
109

4
  records_of->insert(make_pair(perf_name, PerformanceData()));
110
111
4
  PerformanceData &perf_info = records_of->find(perf_name)->second;
112
113
  // Take ctime
114
4
  perf_info.clock_start = take_time();
115
116
  // If this is a new start (i.e. not a restart)
117
  //  if (!perf_info.paused)
118
  //    perf_info.last_time = 0;
119
120
4
  perf_info.paused = false;
121
}
122
123
4
void Stopwatch::stop(string perf_name) {
124
4
  if (!active) return;
125
126
4
  long double clock_end = take_time();
127
128
  // Try to recover performance data
129

4
  if (!performance_exists(perf_name))
130
    throw StopwatchException("Performance not initialized.");
131
132
4
  PerformanceData &perf_info = records_of->find(perf_name)->second;
133
134
  // check whether the performance has been reset
135
4
  if (perf_info.clock_start == 0) return;
136
137
4
  perf_info.stops++;
138
4
  long double lapse = clock_end - perf_info.clock_start;
139
140
4
  if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
141
142
  // Update last time
143
4
  perf_info.last_time = lapse;
144
145
  // Update min/max time
146
4
  if (lapse >= perf_info.max_time) perf_info.max_time = lapse;
147

4
  if (lapse <= perf_info.min_time || perf_info.min_time == 0)
148
4
    perf_info.min_time = lapse;
149
150
  // Update total time
151
4
  perf_info.total_time += lapse;
152
}
153
154
void Stopwatch::pause(string perf_name) {
155
  if (!active) return;
156
157
  long double clock_end = clock();
158
159
  // Try to recover performance data
160
  if (!performance_exists(perf_name))
161
    throw StopwatchException("Performance not initialized.");
162
163
  PerformanceData &perf_info = records_of->find(perf_name)->second;
164
165
  // check whether the performance has been reset
166
  if (perf_info.clock_start == 0) return;
167
168
  long double lapse = clock_end - perf_info.clock_start;
169
170
  // Update total time
171
  perf_info.last_time += lapse;
172
  perf_info.total_time += lapse;
173
}
174
175
void Stopwatch::reset_all() {
176
  if (!active) return;
177
178
  map<string, PerformanceData>::iterator it;
179
180
  for (it = records_of->begin(); it != records_of->end(); ++it) {
181
    reset(it->first);
182
  }
183
}
184
185
void Stopwatch::report_all(int precision, std::ostream &output) {
186
  if (!active) return;
187
188
  output << "\n*** PROFILING RESULTS [ms] (min - avg - max - lastTime - "
189
            "nSamples - totalTime) ***\n";
190
  map<string, PerformanceData>::iterator it;
191
  for (it = records_of->begin(); it != records_of->end(); ++it) {
192
    report(it->first, precision, output);
193
  }
194
}
195
196
void Stopwatch::reset(string perf_name) {
197
  if (!active) return;
198
199
  // Try to recover performance data
200
  if (!performance_exists(perf_name))
201
    throw StopwatchException("Performance not initialized.");
202
203
  PerformanceData &perf_info = records_of->find(perf_name)->second;
204
205
  perf_info.clock_start = 0;
206
  perf_info.total_time = 0;
207
  perf_info.min_time = 0;
208
  perf_info.max_time = 0;
209
  perf_info.last_time = 0;
210
  perf_info.paused = false;
211
  perf_info.stops = 0;
212
}
213
214
void Stopwatch::turn_on() {
215
  std::cout << "Stopwatch active." << std::endl;
216
  active = true;
217
}
218
219
void Stopwatch::turn_off() {
220
  std::cout << "Stopwatch inactive." << std::endl;
221
  active = false;
222
}
223
224
void Stopwatch::report(string perf_name, int precision, std::ostream &output) {
225
  if (!active) return;
226
227
  // Try to recover performance data
228
  if (!performance_exists(perf_name))
229
    throw StopwatchException("Performance not initialized.");
230
231
  PerformanceData &perf_info = records_of->find(perf_name)->second;
232
233
  string pad = "";
234
  for (size_t i = perf_name.length(); i < STOP_WATCH_MAX_NAME_LENGTH; i++)
235
    pad.append(" ");
236
237
  output << perf_name << pad;
238
  output << std::fixed << std::setprecision(precision)
239
         << (perf_info.min_time * 1e3) << "\t";
240
  output << std::fixed << std::setprecision(precision)
241
         << (perf_info.total_time * 1e3 / (long double)perf_info.stops) << "\t";
242
  output << std::fixed << std::setprecision(precision)
243
         << (perf_info.max_time * 1e3) << "\t";
244
  output << std::fixed << std::setprecision(precision)
245
         << (perf_info.last_time * 1e3) << "\t";
246
  output << std::fixed << std::setprecision(precision) << perf_info.stops
247
         << std::endl;
248
  output << std::fixed << std::setprecision(precision)
249
         << perf_info.total_time * 1e3 << std::endl;
250
}
251
252
long double Stopwatch::get_time_so_far(string perf_name) {
253
  // Try to recover performance data
254
  if (!performance_exists(perf_name))
255
    throw StopwatchException("Performance not initialized.");
256
257
  long double lapse =
258
      (take_time() - (records_of->find(perf_name)->second).clock_start);
259
260
  if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
261
262
  return lapse;
263
}
264
265
long double Stopwatch::get_total_time(string perf_name) {
266
  // Try to recover performance data
267
  if (!performance_exists(perf_name))
268
    throw StopwatchException("Performance not initialized.");
269
270
  PerformanceData &perf_info = records_of->find(perf_name)->second;
271
272
  return perf_info.total_time;
273
}
274
275
long double Stopwatch::get_average_time(string perf_name) {
276
  // Try to recover performance data
277
  if (!performance_exists(perf_name))
278
    throw StopwatchException("Performance not initialized.");
279
280
  PerformanceData &perf_info = records_of->find(perf_name)->second;
281
282
  return (perf_info.total_time / (long double)perf_info.stops);
283
}
284
285
long double Stopwatch::get_min_time(string perf_name) {
286
  // Try to recover performance data
287
  if (!performance_exists(perf_name))
288
    throw StopwatchException("Performance not initialized.");
289
290
  PerformanceData &perf_info = records_of->find(perf_name)->second;
291
292
  return perf_info.min_time;
293
}
294
295
long double Stopwatch::get_max_time(string perf_name) {
296
  // Try to recover performance data
297
  if (!performance_exists(perf_name))
298
    throw StopwatchException("Performance not initialized.");
299
300
  PerformanceData &perf_info = records_of->find(perf_name)->second;
301
302
  return perf_info.max_time;
303
}
304
305
long double Stopwatch::get_last_time(string perf_name) {
306
  // Try to recover performance data
307
  if (!performance_exists(perf_name))
308
    throw StopwatchException("Performance not initialized.");
309
310
  PerformanceData &perf_info = records_of->find(perf_name)->second;
311
312
  return perf_info.last_time;
313
}