GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/utils/stop-watch.cpp Lines: 0 140 0.0 %
Date: 2024-02-02 08:47:34 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
}