GCC Code Coverage Report


Directory: ./
File: src/utils/stop-watch.cpp
Date: 2024-08-26 20:29:39
Exec Total Coverage
Lines: 0 140 0.0%
Branches: 0 190 0.0%

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 #include "tsid/utils/Stdafx.hh"
28
29 #ifndef WIN32
30 #include <sys/time.h>
31 #else
32 #include <Windows.h>
33 #include <iomanip>
34 #endif
35
36 #include <iomanip> // std::setprecision
37 #include "tsid/utils/stop-watch.hpp"
38
39 using std::map;
40 using std::ostringstream;
41 using std::string;
42
43 Stopwatch& getProfiler() {
44 static Stopwatch s(REAL_TIME); // alternatives are CPU_TIME and REAL_TIME
45 return s;
46 }
47
48 Stopwatch::Stopwatch(StopwatchMode _mode) : active(true), mode(_mode) {
49 records_of = new map<string, PerformanceData>();
50 }
51
52 Stopwatch::~Stopwatch() { delete records_of; }
53
54 void Stopwatch::set_mode(StopwatchMode new_mode) { mode = new_mode; }
55
56 bool Stopwatch::performance_exists(string perf_name) {
57 return (records_of->find(perf_name) != records_of->end());
58 }
59
60 long double Stopwatch::take_time() {
61 if (mode == CPU_TIME) {
62 // Use ctime
63 return clock();
64
65 } else if (mode == REAL_TIME) {
66 // Query operating system
67
68 #ifdef WIN32
69 /* In case of usage under Windows */
70 FILETIME ft;
71 LARGE_INTEGER intervals;
72
73 // Get the amount of 100 nanoseconds intervals elapsed since January 1, 1601
74 // (UTC)
75 GetSystemTimeAsFileTime(&ft);
76 intervals.LowPart = ft.dwLowDateTime;
77 intervals.HighPart = ft.dwHighDateTime;
78
79 long double measure = intervals.QuadPart;
80 measure -= 116444736000000000.0; // Convert to UNIX epoch time
81 measure /= 10000000.0; // Convert to seconds
82
83 return measure;
84 #else
85 /* Linux, MacOS, ... */
86 struct timeval tv;
87 gettimeofday(&tv, NULL);
88
89 long double measure = tv.tv_usec;
90 measure /= 1000000.0; // Convert to seconds
91 measure += tv.tv_sec; // Add seconds part
92
93 return measure;
94 #endif
95
96 } else {
97 // If mode == NONE, clock has not been initialized, then throw exception
98 throw StopwatchException("Clock not initialized to a time taking mode!");
99 }
100 }
101
102 void Stopwatch::start(string perf_name) {
103 if (!active) return;
104
105 // Just works if not already present
106 records_of->insert(make_pair(perf_name, PerformanceData()));
107
108 PerformanceData& perf_info = records_of->find(perf_name)->second;
109
110 // Take ctime
111 perf_info.clock_start = take_time();
112
113 // If this is a new start (i.e. not a restart)
114 // if (!perf_info.paused)
115 // perf_info.last_time = 0;
116
117 perf_info.paused = false;
118 }
119
120 void Stopwatch::stop(string perf_name) {
121 if (!active) return;
122
123 long double clock_end = take_time();
124
125 // Try to recover performance data
126 if (!performance_exists(perf_name))
127 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)
145 perf_info.min_time = lapse;
146
147 // Update total time
148 perf_info.total_time += lapse;
149 }
150
151 void Stopwatch::pause(string perf_name) {
152 if (!active) return;
153
154 long double clock_end = clock();
155
156 // Try to recover performance data
157 if (!performance_exists(perf_name))
158 throw StopwatchException("Performance not initialized.");
159
160 PerformanceData& perf_info = records_of->find(perf_name)->second;
161
162 // check whether the performance has been reset
163 if (perf_info.clock_start == 0) return;
164
165 long double lapse = clock_end - perf_info.clock_start;
166
167 // Update total time
168 perf_info.last_time += lapse;
169 perf_info.total_time += lapse;
170 }
171
172 void Stopwatch::reset_all() {
173 if (!active) return;
174
175 map<string, PerformanceData>::iterator it;
176
177 for (it = records_of->begin(); it != records_of->end(); ++it) {
178 reset(it->first);
179 }
180 }
181
182 void Stopwatch::report_all(int precision, std::ostream& output) {
183 if (!active) return;
184
185 output << "\n"
186 << std::setw(STOP_WATCH_MAX_NAME_LENGTH) << std::left
187 << "*** PROFILING RESULTS [ms] ";
188 output << std::setw(STOP_WATCH_TIME_WIDTH) << "min"
189 << " ";
190 output << std::setw(STOP_WATCH_TIME_WIDTH) << "avg"
191 << " ";
192 output << std::setw(STOP_WATCH_TIME_WIDTH) << "max"
193 << " ";
194 output << std::setw(STOP_WATCH_TIME_WIDTH) << "lastTime"
195 << " ";
196 output << std::setw(STOP_WATCH_TIME_WIDTH) << "nSamples"
197 << " ";
198 output << std::setw(STOP_WATCH_TIME_WIDTH) << "totalTime"
199 << " ***\n";
200 map<string, PerformanceData>::iterator it;
201 for (it = records_of->begin(); it != records_of->end(); ++it) {
202 if (it->second.stops > 0) report(it->first, precision, output);
203 }
204 }
205
206 void Stopwatch::reset(string perf_name) {
207 if (!active) return;
208
209 // Try to recover performance data
210 if (!performance_exists(perf_name))
211 throw StopwatchException("Performance not initialized.");
212
213 PerformanceData& perf_info = records_of->find(perf_name)->second;
214
215 perf_info.clock_start = 0;
216 perf_info.total_time = 0;
217 perf_info.min_time = 0;
218 perf_info.max_time = 0;
219 perf_info.last_time = 0;
220 perf_info.paused = false;
221 perf_info.stops = 0;
222 }
223
224 void Stopwatch::turn_on() {
225 std::cout << "Stopwatch active." << std::endl;
226 active = true;
227 }
228
229 void Stopwatch::turn_off() {
230 std::cout << "Stopwatch inactive." << std::endl;
231 active = false;
232 }
233
234 void Stopwatch::report(string perf_name, int precision, std::ostream& output) {
235 if (!active) return;
236
237 // Try to recover performance data
238 if (!performance_exists(perf_name))
239 throw StopwatchException("Performance not initialized.");
240
241 PerformanceData& perf_info = records_of->find(perf_name)->second;
242
243 output << std::setw(STOP_WATCH_MAX_NAME_LENGTH) << std::left << perf_name;
244 output << std::fixed << std::setprecision(precision)
245 << std::setw(STOP_WATCH_TIME_WIDTH) << (perf_info.min_time * 1e3)
246 << " ";
247 output << std::fixed << std::setprecision(precision)
248 << std::setw(STOP_WATCH_TIME_WIDTH)
249 << (perf_info.total_time * 1e3 / (long double)perf_info.stops) << " ";
250 output << std::fixed << std::setprecision(precision)
251 << std::setw(STOP_WATCH_TIME_WIDTH) << (perf_info.max_time * 1e3)
252 << " ";
253 output << std::fixed << std::setprecision(precision)
254 << std::setw(STOP_WATCH_TIME_WIDTH) << (perf_info.last_time * 1e3)
255 << " ";
256 output << std::fixed << std::setprecision(precision)
257 << std::setw(STOP_WATCH_TIME_WIDTH) << perf_info.stops << " ";
258 output << std::fixed << std::setprecision(precision)
259 << std::setw(STOP_WATCH_TIME_WIDTH) << perf_info.total_time * 1e3
260 << std::endl;
261 }
262
263 long double Stopwatch::get_time_so_far(string perf_name) {
264 // Try to recover performance data
265 if (!performance_exists(perf_name))
266 throw StopwatchException("Performance not initialized.");
267
268 long double lapse =
269 (take_time() - (records_of->find(perf_name)->second).clock_start);
270
271 if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
272
273 return lapse;
274 }
275
276 long double Stopwatch::get_total_time(string perf_name) {
277 // Try to recover performance data
278 if (!performance_exists(perf_name))
279 throw StopwatchException("Performance not initialized.");
280
281 PerformanceData& perf_info = records_of->find(perf_name)->second;
282
283 return perf_info.total_time;
284 }
285
286 long double Stopwatch::get_average_time(string perf_name) {
287 // Try to recover performance data
288 if (!performance_exists(perf_name))
289 throw StopwatchException("Performance not initialized.");
290
291 PerformanceData& perf_info = records_of->find(perf_name)->second;
292
293 return (perf_info.total_time / (long double)perf_info.stops);
294 }
295
296 long double Stopwatch::get_min_time(string perf_name) {
297 // Try to recover performance data
298 if (!performance_exists(perf_name))
299 throw StopwatchException("Performance not initialized.");
300
301 PerformanceData& perf_info = records_of->find(perf_name)->second;
302
303 return perf_info.min_time;
304 }
305
306 long double Stopwatch::get_max_time(string perf_name) {
307 // Try to recover performance data
308 if (!performance_exists(perf_name))
309 throw StopwatchException("Performance not initialized.");
310
311 PerformanceData& perf_info = records_of->find(perf_name)->second;
312
313 return perf_info.max_time;
314 }
315
316 long double Stopwatch::get_last_time(string perf_name) {
317 // Try to recover performance data
318 if (!performance_exists(perf_name))
319 throw StopwatchException("Performance not initialized.");
320
321 PerformanceData& perf_info = records_of->find(perf_name)->second;
322
323 return perf_info.last_time;
324 }
325