Line |
Branch |
Exec |
Source |
1 |
|
|
// Copyright (c) 2015, LAAS-CNRS |
2 |
|
|
// Authors: Thomas Moulard, Joseph Mirabel |
3 |
|
|
// |
4 |
|
|
|
5 |
|
|
// Redistribution and use in source and binary forms, with or without |
6 |
|
|
// modification, are permitted provided that the following conditions are |
7 |
|
|
// met: |
8 |
|
|
// |
9 |
|
|
// 1. Redistributions of source code must retain the above copyright |
10 |
|
|
// notice, this list of conditions and the following disclaimer. |
11 |
|
|
// |
12 |
|
|
// 2. Redistributions in binary form must reproduce the above copyright |
13 |
|
|
// notice, this list of conditions and the following disclaimer in the |
14 |
|
|
// documentation and/or other materials provided with the distribution. |
15 |
|
|
// |
16 |
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 |
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 |
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 |
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 |
|
|
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 |
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 |
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 |
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 |
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 |
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 |
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
27 |
|
|
// DAMAGE. |
28 |
|
|
|
29 |
|
|
#ifndef HPP_UTIL_TIMER_HH |
30 |
|
|
#define HPP_UTIL_TIMER_HH |
31 |
|
|
|
32 |
|
|
#include <chrono> |
33 |
|
|
#include <hpp/util/config.hh> |
34 |
|
|
#include <hpp/util/debug.hh> |
35 |
|
|
|
36 |
|
|
namespace hpp { |
37 |
|
|
namespace debug { |
38 |
|
|
class HPP_UTIL_DLLAPI Timer { |
39 |
|
|
public: |
40 |
|
|
typedef std::chrono::steady_clock clock_type; |
41 |
|
|
typedef clock_type::time_point time_point; |
42 |
|
|
typedef std::chrono::duration<double> duration_type; |
43 |
|
|
|
44 |
|
|
explicit Timer(bool autoStart = false); |
45 |
|
|
Timer(const Timer&); |
46 |
|
|
Timer& operator=(const Timer&); |
47 |
|
|
~Timer(); |
48 |
|
|
|
49 |
|
|
const time_point& start(); |
50 |
|
|
const time_point& stop(); |
51 |
|
|
double duration() const; |
52 |
|
|
|
53 |
|
|
const time_point& getStart() const; |
54 |
|
|
const time_point& getStop() const; |
55 |
|
|
|
56 |
|
|
std::ostream& print(std::ostream&) const; |
57 |
|
|
|
58 |
|
|
private: |
59 |
|
|
time_point start_; |
60 |
|
|
time_point end_; |
61 |
|
|
}; |
62 |
|
|
|
63 |
|
|
#ifdef HPP_ENABLE_BENCHMARK |
64 |
|
|
|
65 |
|
|
#define hppStartBenchmark(ID) \ |
66 |
|
|
hppDout(benchmark, #ID << ": start"); \ |
67 |
|
|
::hpp::debug::Timer _##ID##_timer_(true) |
68 |
|
|
|
69 |
|
|
#define hppStopBenchmark(ID) \ |
70 |
|
|
do { \ |
71 |
|
|
_##ID##_timer_.stop(); \ |
72 |
|
|
hppDout(benchmark, #ID << ": stop"); \ |
73 |
|
|
} while (0) |
74 |
|
|
|
75 |
|
|
#define hppDisplayBenchmark(ID) \ |
76 |
|
|
hppDout(benchmark, #ID << ": " << _##ID##_timer_.duration()); |
77 |
|
|
|
78 |
|
|
#define hppBenchmark(data) \ |
79 |
|
|
do { \ |
80 |
|
|
using namespace hpp; \ |
81 |
|
|
using namespace ::hpp::debug; \ |
82 |
|
|
std::stringstream __ss; \ |
83 |
|
|
__ss << data << iendl; \ |
84 |
|
|
logging.benchmark.write(__FILE__, __LINE__, __PRETTY_FUNCTION__, __ss); \ |
85 |
|
|
} while (0) |
86 |
|
|
|
87 |
|
|
#else |
88 |
|
|
#define hppStartBenchmark(ID) |
89 |
|
|
#define hppStopBenchmark(ID) |
90 |
|
|
#define hppDisplayBenchmark(ID) |
91 |
|
|
#define hppBenchmark(data) |
92 |
|
|
#endif // HPP_ENABLE_BENCHMARK |
93 |
|
|
|
94 |
|
|
/// \brief Computation of min, max and mean time from a set of measurements. |
95 |
|
|
class HPP_UTIL_DLLAPI TimeCounter { |
96 |
|
|
public: |
97 |
|
|
struct Scope { |
98 |
|
10 |
Scope(TimeCounter& t) : tc(t) { t.start(); } |
99 |
|
10 |
~Scope() { tc.stop(); } |
100 |
|
|
|
101 |
|
|
TimeCounter& tc; |
102 |
|
|
}; |
103 |
|
|
|
104 |
|
|
typedef std::chrono::system_clock clock_type; |
105 |
|
|
typedef clock_type::time_point time_point; |
106 |
|
|
typedef std::chrono::duration<double> duration_type; |
107 |
|
|
|
108 |
|
|
TimeCounter(const std::string& name); |
109 |
|
|
|
110 |
|
|
void start(); |
111 |
|
|
double stop(); |
112 |
|
|
double last(); |
113 |
|
|
void reset(); |
114 |
|
|
|
115 |
|
|
double min() const; |
116 |
|
|
double max() const; |
117 |
|
|
double mean() const; |
118 |
|
|
double totalTime() const; |
119 |
|
|
|
120 |
|
|
std::ostream& print(std::ostream& os) const; |
121 |
|
|
|
122 |
|
|
private: |
123 |
|
|
std::string n_; |
124 |
|
|
unsigned long c_; |
125 |
|
|
duration_type t_, last_, min_, max_; |
126 |
|
|
time_point s_; |
127 |
|
|
}; |
128 |
|
|
|
129 |
|
|
std::ostream& operator<<(std::ostream& os, const TimeCounter& tc); |
130 |
|
|
|
131 |
|
|
#ifdef HPP_ENABLE_BENCHMARK |
132 |
|
|
|
133 |
|
|
/// \addtogroup hpp_util_logging |
134 |
|
|
/// \{ |
135 |
|
|
|
136 |
|
|
/// \brief Define a new TimeCounter |
137 |
|
|
#define HPP_DEFINE_TIMECOUNTER(name) \ |
138 |
|
|
::hpp::debug::TimeCounter _##name##_timecounter_(#name) |
139 |
|
|
/// \brief Compute the time spent in the current scope. |
140 |
|
|
#define HPP_SCOPE_TIMECOUNTER(name) \ |
141 |
|
|
::hpp::debug::TimeCounter::Scope _##name##_scopetimecounter_( \ |
142 |
|
|
_##name##_timecounter_) |
143 |
|
|
/// \brief Start a watch. |
144 |
|
|
#define HPP_START_TIMECOUNTER(name) _##name##_timecounter_.start() |
145 |
|
|
/// \brief Stop a watch and save elapsed time. |
146 |
|
|
#define HPP_STOP_TIMECOUNTER(name) _##name##_timecounter_.stop() |
147 |
|
|
/// \brief Print last elapsed time to the logs. |
148 |
|
|
#define HPP_DISPLAY_LAST_TIMECOUNTER(name) \ |
149 |
|
|
do { \ |
150 |
|
|
using namespace hpp; \ |
151 |
|
|
using namespace ::hpp::debug; \ |
152 |
|
|
std::stringstream __ss; \ |
153 |
|
|
__ss << #name << " last: " << _##name##_timecounter_.last() << iendl; \ |
154 |
|
|
logging.benchmark.write(__FILE__, __LINE__, __PRETTY_FUNCTION__, __ss); \ |
155 |
|
|
} while (0) |
156 |
|
|
/// \brief Print min, max and mean time of the time measurements. |
157 |
|
|
#define HPP_DISPLAY_TIMECOUNTER(name) \ |
158 |
|
|
do { \ |
159 |
|
|
using namespace hpp; \ |
160 |
|
|
using namespace ::hpp::debug; \ |
161 |
|
|
std::stringstream __ss; \ |
162 |
|
|
__ss << _##name##_timecounter_ << iendl; \ |
163 |
|
|
logging.benchmark.write(__FILE__, __LINE__, __PRETTY_FUNCTION__, __ss); \ |
164 |
|
|
} while (0) |
165 |
|
|
/// \brief Reset a TimeCounter. |
166 |
|
|
#define HPP_RESET_TIMECOUNTER(name) _##name##_timecounter_.reset(); |
167 |
|
|
/// \brief Stream (\c operator<<) to the output stream. |
168 |
|
|
#define HPP_STREAM_TIMECOUNTER(os, name) os << _##name##_timecounter_ |
169 |
|
|
/// \} |
170 |
|
|
#else // HPP_ENABLE_BENCHMARK |
171 |
|
|
#define HPP_DEFINE_TIMECOUNTER(name) \ |
172 |
|
|
struct _##name##_EndWithSemiColon_ {} |
173 |
|
|
#define HPP_SCOPE_TIMECOUNTER(name) |
174 |
|
|
#define HPP_START_TIMECOUNTER(name) |
175 |
|
|
#define HPP_STOP_TIMECOUNTER(name) |
176 |
|
|
#define HPP_DISPLAY_LAST_TIMECOUNTER(name) |
177 |
|
|
#define HPP_DISPLAY_TIMECOUNTER(name) |
178 |
|
|
#define HPP_RESET_TIMECOUNTER(name) |
179 |
|
|
#define HPP_STREAM_TIMECOUNTER(os, name) os |
180 |
|
|
#endif // HPP_ENABLE_BENCHMARK |
181 |
|
|
|
182 |
|
|
#define HPP_STOP_AND_DISPLAY_TIMECOUNTER(name) \ |
183 |
|
|
HPP_STOP_TIMECOUNTER(name); \ |
184 |
|
|
HPP_DISPLAY_TIMECOUNTER(name) |
185 |
|
|
|
186 |
|
|
} // end of namespace debug |
187 |
|
|
} // end of namespace hpp |
188 |
|
|
|
189 |
|
|
#endif // HPP_UTIL_TIMER_HH |
190 |
|
|
|