GCC Code Coverage Report


Directory: ./
File: src/core/utils/stop-watch.cpp
Date: 2025-01-16 08:47:40
Exec Total Coverage
Lines: 9 145 6.2%
Branches: 5 186 2.7%

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