GCC Code Coverage Report


Directory: ./
File: src/utils/stop-watch.cpp
Date: 2024-08-13 12:13:25
Exec Total Coverage
Lines: 37 132 28.0%
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
4/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
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
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
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
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 return (records_of->find(perf_name) != records_of->end());
61 }
62
63 8 long double Stopwatch::take_time() {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (mode == CPU_TIME) {
65 // Use ctime
66 return clock();
67
68
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!active) return;
107
108 // Just works if not already present
109
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!active) return;
125
126 4 long double clock_end = take_time();
127
128 // Try to recover performance data
129
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
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
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (lapse >= perf_info.max_time) perf_info.max_time = lapse;
147
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
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 }
314