Thrill  0.1
timer.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/common/timer.hpp
3  *
4  * Part of FOXXLL. See http://foxxll.org
5  *
6  * Copyright (C) 2002, 2005 Roman Dementiev <[email protected]>
7  * Copyright (C) 2007-2009 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2008 Johannes Singler <[email protected]>
9  * Copyright (C) 2013-2014 Timo Bingmann <[email protected]>
10  *
11  * Distributed under the Boost Software License, Version 1.0.
12  * (See accompanying file LICENSE_1_0.txt or copy at
13  * http://www.boost.org/LICENSE_1_0.txt)
14  **************************************************************************/
15 
16 #ifndef FOXXLL_COMMON_TIMER_HEADER
17 #define FOXXLL_COMMON_TIMER_HEADER
18 
19 #include <chrono>
20 #include <limits>
21 #include <mutex>
22 #include <string>
23 
24 #include <tlx/logger/core.hpp>
25 
26 #include <foxxll/common/utils.hpp>
27 #include <foxxll/config.hpp>
29 
30 namespace foxxll {
31 
32 //! \addtogroup foxxll_support
33 //! \{
34 
35 //! Returns number of seconds since the epoch, high resolution.
36 static inline double timestamp()
37 {
38  return static_cast<double>(
39  std::chrono::duration_cast<std::chrono::microseconds>(
40  std::chrono::steady_clock::now().time_since_epoch()
41  ).count()) / 1e6;
42 }
43 
44 /*!
45  * Class timer is a simple stop watch timer. It uses the timestamp() function
46  * to get the current time when start() is called. Then, after some processing,
47  * the function stop() functions can be called, or seconds() and other
48  * accessors can be called directly.
49  */
50 class timer
51 {
52  //! boolean whether the stopwatch timer is currently running
53  bool running;
54 
55  //! total accumulated time in seconds.
56  double accumulated;
57 
58  //! last start time of the stopwatch
59  double last_clock;
60 
61  //! return current timestamp
62  static inline double timestamp()
63  {
64  return foxxll::timestamp();
65  }
66 
67  //! guard accumulated
68  mutable std::mutex mutex_accumulated;
69 
70 public:
71  //! boolean indicating that this class does real timing
72  static const bool is_real = true;
73 
74  //! initialize and optionally immediately start the timer
75  explicit timer(bool start_immediately = false)
76  : running(false), accumulated(0), last_clock(0)
77  {
78  if (start_immediately) start();
79  }
80 
81  //! start timer
82  void start()
83  {
84  running = true;
85  last_clock = timestamp();
86  }
87 
88  //! stop timer
89  void stop()
90  {
91  running = false;
92  auto delta = timestamp() - last_clock;
93 
94  std::unique_lock<std::mutex> lock(mutex_accumulated);
95  accumulated += delta;
96  }
97 
98  //! return accumulated time
99  void reset()
100  {
101  std::unique_lock<std::mutex> lock(mutex_accumulated);
102  accumulated = 0.;
103  last_clock = timestamp();
104  }
105 
106  //! return currently accumulated time in milliseconds
107  double mseconds() const
108  {
109  std::unique_lock<std::mutex> lock(mutex_accumulated);
110 
111  if (running)
112  return (accumulated + timestamp() - last_clock) * 1000.;
113 
114  return (accumulated * 1000.);
115  }
116 
117  //! return currently accumulated time in microseconds
118  double useconds() const
119  {
120  auto delta = timestamp() - last_clock;
121 
122  std::unique_lock<std::mutex> lock(mutex_accumulated);
123 
124  if (running)
125  return (accumulated + delta) * 1000000.;
126 
127  return (accumulated * 1000000.);
128  }
129 
130  //! return currently accumulated time in seconds (as double)
131  double seconds() const
132  {
133  auto delta = timestamp() - last_clock;
134 
135  std::unique_lock<std::mutex> lock(mutex_accumulated);
136 
137  if (running)
138  return (accumulated + delta);
139 
140  return (accumulated);
141  }
142 
143  //! accumulate elapsed time from another timer
145  {
146  auto delta = tm.seconds();
147  std::unique_lock<std::mutex> lock(mutex_accumulated);
148 
149  accumulated += delta;
150  return *this;
151  }
152 
153  //! direct <<-operator for ostream. Can be used for printing with std::cout.
154  friend std::ostream& operator << (std::ostream& os, const timer& t)
155  {
156  return os << t.seconds() << 's';
157  }
158 };
159 
160 /*!
161  * Class fake_timer is a drop-in replacement for timer, which does
162  * nothing. Using the fake class, timers can quickly be disabled in release
163  * builds, but still be available for debugging session.
164  *
165  * \see timer
166  */
168 {
169 public:
170  //! boolean indicating that this class does NOT do real timing
171  static const bool is_real = false;
172 
173  //! initialize and optionally immediately start the timer
174  explicit fake_timer(bool = false)
175  { }
176 
177  //! start timer
178  void start()
179  { }
180 
181  //! stop timer
182  void stop()
183  { }
184 
185  //! return accumulated time
186  void reset()
187  { }
188 
189  //! return currently accumulated time in milliseconds
190  double mseconds() const
191  {
192  return std::numeric_limits<double>::quiet_NaN();
193  }
194 
195  //! return currently accumulated time in microseconds
196  double useconds() const
197  {
198  return std::numeric_limits<double>::quiet_NaN();
199  }
200 
201  //! return currently accumulated time in seconds (as double)
202  double seconds() const
203  {
204  return std::numeric_limits<double>::quiet_NaN();
205  }
206 
207  //! accumulate elapsed time from another timer
209  {
210  return *this;
211  }
212 
213  //! direct <<-operator for ostream. Can be used for printing with std::cout.
214  friend std::ostream& operator << (std::ostream& os, const fake_timer& t)
215  {
216  return os << t.seconds() << 's';
217  }
218 };
219 
220 /*!
221  * Simple scoped timer, which takes a text message and prints the duration
222  * until the scope is destroyed.
223  */
225 {
226 protected:
227  //! message
229 
230  //! bytes processed
231  uint64_t m_bytes;
232 
233  //! timer
235 
236 public:
237  //! save message and start timer
238  explicit scoped_print_timer(const std::string& message, const uint64_t bytes = 0)
239  : m_message(message),
240  m_bytes(bytes),
241  m_timer(true)
242  {
243  TLX_LOG1 << "Starting " << message;
244  }
245 
246  //! on destruction: tell the time
248  {
249  if (m_bytes == 0) {
250  TLX_LOG1 << "Finished "
251  << m_message
252  << " after " << m_timer.seconds() << " seconds";
253  }
254  else {
255  double bps = static_cast<double>(m_bytes) / m_timer.seconds();
256 
257  TLX_LOG1
258  << "Finished "
259  << m_message
260  << " after " << m_timer.seconds() << " seconds. "
261  << "Processed " << tlx::format_iec_units(m_bytes) << "B"
262  << " @ " << tlx::format_iec_units(static_cast<uint64_t>(bps)) << "B/s";
263  }
264  }
265 
266  //! constant access to enclosed timer
267  const foxxll::timer & timer() const
268  {
269  return m_timer;
270  }
271 };
272 
273 //! \}
274 
275 } // namespace foxxll
276 
277 #endif // !FOXXLL_COMMON_TIMER_HEADER
278 
279 /**************************************************************************/
void start()
start timer
Definition: timer.hpp:82
Class fake_timer is a drop-in replacement for timer, which does nothing.
Definition: timer.hpp:167
timer(bool start_immediately=false)
initialize and optionally immediately start the timer
Definition: timer.hpp:75
static const bool is_real
boolean indicating that this class does real timing
Definition: timer.hpp:72
double accumulated
total accumulated time in seconds.
Definition: timer.hpp:56
Simple scoped timer, which takes a text message and prints the duration until the scope is destroyed...
Definition: timer.hpp:224
double mseconds() const
return currently accumulated time in milliseconds
Definition: timer.hpp:190
void start()
start timer
Definition: timer.hpp:178
static constexpr double delta
Definition: select.hpp:35
~scoped_print_timer()
on destruction: tell the time
Definition: timer.hpp:247
void stop()
stop timer
Definition: timer.hpp:89
foxxll::timer m_timer
timer
Definition: timer.hpp:234
static double timestamp()
Returns number of seconds since the epoch, high resolution.
Definition: timer.hpp:36
const foxxll::timer & timer() const
constant access to enclosed timer
Definition: timer.hpp:267
static double timestamp()
return current timestamp
Definition: timer.hpp:62
uint64_t m_bytes
bytes processed
Definition: timer.hpp:231
friend std::ostream & operator<<(std::ostream &os, const timer &t)
direct <<-operator for ostream. Can be used for printing with std::cout.
Definition: timer.hpp:154
double mseconds() const
return currently accumulated time in milliseconds
Definition: timer.hpp:107
FOXXLL library namespace
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220
std::string m_message
message
Definition: timer.hpp:228
double seconds() const
return currently accumulated time in seconds (as double)
Definition: timer.hpp:202
void stop()
stop timer
Definition: timer.hpp:182
Class timer is a simple stop watch timer.
Definition: timer.hpp:50
static const size_t bytes
number of bytes in uint_pair
Definition: uint_types.hpp:75
double useconds() const
return currently accumulated time in microseconds
Definition: timer.hpp:196
double seconds() const
return currently accumulated time in seconds (as double)
Definition: timer.hpp:131
bool running
boolean whether the stopwatch timer is currently running
Definition: timer.hpp:53
scoped_print_timer(const std::string &message, const uint64_t bytes=0)
save message and start timer
Definition: timer.hpp:238
fake_timer(bool=false)
initialize and optionally immediately start the timer
Definition: timer.hpp:174
#define TLX_LOG1
Definition: core.hpp:145
double last_clock
last start time of the stopwatch
Definition: timer.hpp:59
timer & operator+=(const timer &tm)
accumulate elapsed time from another timer
Definition: timer.hpp:144
double useconds() const
return currently accumulated time in microseconds
Definition: timer.hpp:118
void reset()
return accumulated time
Definition: timer.hpp:186
void reset()
return accumulated time
Definition: timer.hpp:99
std::mutex mutex_accumulated
guard accumulated
Definition: timer.hpp:68
std::string format_iec_units(uint64_t number, int precision=3)
Format number as something like 1 TiB.