vSMC
vSMC: Scalable Monte Carlo
stop_watch.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/utility/stop_watch.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_UTILITY_STOP_WATCH_HPP
33 #define VSMC_UTILITY_STOP_WATCH_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #if VSMC_HAS_CXX11LIB_CHRONO
38 #include <chrono>
39 #endif
40 
44 #ifndef VSMC_STOP_WATCH_CHRONO_CLOCK_TYPE
45 #define VSMC_STOP_WATCH_CHRONO_CLOCK_TYPE std::chrono::high_resolution_clock
46 #endif
47 
50 #ifndef VSMC_STOP_WATCH_TYPE
51 #if VSMC_HAS_CXX11LIB_CHRONO
52 #define VSMC_STOP_WATCH_TYPE ::vsmc::StopWatchChrono
53 #elif defined(VSMC_MACOSX) || VSMC_HAS_POSIX || defined(VSMC_MSVC)
54 #define VSMC_STOP_WATCH_TYPE ::vsmc::StopWatchSYS
55 #else
56 #define VSMC_STOP_WATCH_TYPE ::vsmc::StopWatchNull
57 #endif
58 #endif
59 
60 #if defined(VSMC_MACOSX)
61 #include <mach/mach_time.h>
62 #elif VSMC_HAS_POSIX
63 #include <time.h>
64 #elif defined(VSMC_MSVC)
65 #include <windows.h>
66 #endif
67 
68 namespace vsmc {
69 
72 template <typename WatchType>
74 {
75  public :
76 
77  typedef WatchType watch_type;
78 
79  StopWatchGuard (watch_type &watch, bool start = true) :
80  start_(start), watch_(watch) {if (start_) watch_.start();}
81 
82  ~StopWatchGuard () {if (start_) watch_.stop();}
83 
84  private :
85 
86  const bool start_;
87  watch_type &watch_;
88 }; // class StopWatchGuard
89 
96 {
97  public :
98 
99  bool running () const {return false;}
100  bool start () {return false;}
101  bool stop () {return false;}
102  void reset () {}
103 
104  double nanoseconds () const {return 1;}
105  double microseconds () const {return 1e-3;}
106  double milliseconds () const {return 1e-6;}
107  double seconds () const {return 1e-9;}
108  double minutes () const {return 1e-9 / 60;}
109  double hours () const {return 1e-9 / 3600;}
110 }; // class StopWatch
111 
112 #if VSMC_HAS_CXX11LIB_CHRONO
113 
116 template <typename ClockType>
118 {
119  public :
120 
121  typedef ClockType clock_type;
122 
123  StopWatchClockAdapter () : elapsed_(0), running_(false) {reset();}
124 
130  bool running () const {return running_;}
131 
138  bool start ()
139  {
140  if (running_)
141  return false;
142 
143  running_ = true;
144  start_time_ = clock_type::now();
145 
146  return true;
147  }
148 
154  bool stop ()
155  {
156  if (!running_)
157  return false;
158 
159  typename clock_type::time_point stop_time = clock_type::now();
160  elapsed_ += stop_time - start_time_;
161  running_ = false;
162 
163  return true;
164  }
165 
167  void reset ()
168  {
169  start();
170  elapsed_ = typename clock_type::duration(0);
171  running_ = false;
172  }
173 
175  double nanoseconds () const
176  {
177  return std::chrono::duration_cast<std::chrono::duration<
178  double, std::nano> >(elapsed_).count();
179  }
180 
182  double microseconds () const
183  {
184  return std::chrono::duration_cast<std::chrono::duration<
185  double, std::micro> >(elapsed_).count();
186  }
187 
189  double milliseconds () const
190  {
191  return std::chrono::duration_cast<std::chrono::duration<
192  double, std::milli> >(elapsed_).count();
193  }
194 
196  double seconds () const
197  {
198  return std::chrono::duration_cast<std::chrono::duration<
199  double, std::ratio<1> > >(elapsed_).count();
200  }
201 
203  double minutes () const
204  {
205  return std::chrono::duration_cast<std::chrono::duration<
206  double, std::ratio<60> > >(elapsed_).count();
207  }
208 
210  double hours () const
211  {
212  return std::chrono::duration_cast<std::chrono::duration<
213  double, std::ratio<3600> > >(elapsed_).count();
214  }
215 
216  private :
217 
218  typename clock_type::duration elapsed_;
219  typename clock_type::time_point start_time_;
220  bool running_;
221 }; // class StopWatchClockAdapter
222 
225 typedef StopWatchClockAdapter<VSMC_STOP_WATCH_CHRONO_CLOCK_TYPE>
227 
228 #endif // VSMC_HAS_CXX11LIB_CHRONO
229 
230 #if defined(VSMC_MACOSX)
231 
239 {
240  public :
241 
242  StopWatchSYS () : running_(false) {reset();}
243 
244  bool running () {return running_;}
245 
246  bool start ()
247  {
248  if (running_)
249  return false;
250 
251  running_ = true;
252  start_time_ = ::mach_absolute_time();
253 
254  return true;
255  }
256 
257  bool stop ()
258  {
259  if (!running_)
260  return false;
261 
262  uint64_t stop_time = ::mach_absolute_time();
263  uint64_t elapsed_abs = stop_time - start_time_;
264  uint64_t elapsed_nsec = elapsed_abs *
265  timebase_.numer / timebase_.denom;
266  uint64_t inc_sec = elapsed_nsec / ratio_;
267  uint64_t inc_nsec = elapsed_nsec % ratio_;
268  elapsed_sec_ += inc_sec;
269  elapsed_nsec_ += inc_nsec;
270  running_ = false;
271 
272  return true;
273  }
274 
275  void reset ()
276  {
277  start();
278  elapsed_sec_ = 0;
279  elapsed_nsec_ = 0;
280  ::mach_timebase_info(&timebase_);
281  running_ = false;
282  }
283 
284  double nanoseconds () const
285  {return elapsed_sec_ * 1e9 + elapsed_nsec_;}
286 
287  double microseconds () const
288  {return elapsed_sec_ * 1e6 + elapsed_nsec_ * 1e-3;}
289 
290  double milliseconds () const
291  {return elapsed_sec_ * 1e3 + elapsed_nsec_ * 1e-6;}
292 
293  double seconds () const
294  {return elapsed_sec_ + elapsed_nsec_ * 1e-9;}
295 
296  double minutes () const
297  {return seconds() / 60;}
298 
299  double hours () const
300  {return seconds() / 3600;}
301 
302  private :
303 
304  uint64_t elapsed_sec_;
305  uint64_t elapsed_nsec_;
306  uint64_t start_time_;
307  ::mach_timebase_info_data_t timebase_;
308  bool running_;
309  static VSMC_CONSTEXPR const uint64_t ratio_ =
310  static_cast<uint64_t>(1000000000ULL); // 9 zero
311 }; // class StopWatchSYS
312 
313 #elif VSMC_HAS_POSIX
314 
315 class StopWatchSYS
316 {
317  public :
318 
319  StopWatchSYS () : running_(false) {reset();}
320 
321  bool running () {return running_;}
322 
323  bool start ()
324  {
325  if (running_)
326  return false;
327 
328  running_ = true;
329  ::clock_gettime(CLOCK_REALTIME, &start_time_);
330 
331  return true;
332  }
333 
334  bool stop ()
335  {
336  if (!running_)
337  return false;
338 
339  timespec stop_time;
340  ::clock_gettime(CLOCK_REALTIME, &stop_time);
341  time_t sec = stop_time.tv_sec - start_time_.tv_sec;
342  long nsec = stop_time.tv_nsec - start_time_.tv_nsec;
343 
344  time_t inc_sec = sec + nsec / ratio_;
345  long inc_nsec = nsec % ratio_;
346  elapsed_.tv_sec += inc_sec;
347  elapsed_.tv_nsec += inc_nsec;
348  running_ = false;
349 
350  return true;
351  }
352 
353  void reset ()
354  {
355  start();
356  elapsed_.tv_sec = 0;
357  elapsed_.tv_nsec = 0;
358  running_ = false;
359  }
360 
361  double nanoseconds () const
362  {return elapsed_.tv_sec * 1e9 + elapsed_.tv_nsec;}
363 
364  double microseconds () const
365  {return elapsed_.tv_sec * 1e6 + elapsed_.tv_nsec * 1e-3;}
366 
367  double milliseconds () const
368  {return elapsed_.tv_sec * 1e3 + elapsed_.tv_nsec * 1e-6;}
369 
370  double seconds () const
371  {return elapsed_.tv_sec + elapsed_.tv_nsec * 1e-9;}
372 
373  double minutes () const
374  {return seconds() / 60;}
375 
376  double hours () const
377  {return seconds() / 3600;}
378 
379  private :
380 
381  ::timespec elapsed_;
382  ::timespec start_time_;
383  bool running_;
384  static VSMC_CONSTEXPR const long ratio_ = 1000000000L; // 9 zero
385 }; // class StopWatchSYS
386 
387 #elif defined(VSMC_MSVC)
388 
389 class StopWatchSYS
390 {
391  public :
392 
393  StopWatchSYS () :
394  elapsed_(0), start_time_(0), frequency_(0), running_(false)
395  {reset();}
396 
397  bool running () {return running_;}
398 
399  bool start ()
400  {
401  if (running_)
402  return false;
403 
404  running_ = true;
405  LARGE_INTEGER time;
406  ::QueryPerformanceCounter(&time);
407  start_time_ = time.QuadPart;
408 
409  return true;
410  }
411 
412  bool stop ()
413  {
414  if (!running_)
415  return false;
416 
417  LARGE_INTEGER time;
418  ::QueryPerformanceCounter(&time);
419  elapsed_ += time.QuadPart - start_time_;
420  running_ = false;
421 
422  return true;
423  }
424 
425  void reset ()
426  {
427  start();
428  elapsed_ = 0;
429  LARGE_INTEGER freq;
430  ::QueryPerformanceFrequency(&freq);
431  frequency_ = freq.QuadPart;
432  running_ = false;
433  }
434 
435  double nanoseconds () const
436  {return elapsed_ / (frequency_ * 1e-9);}
437 
438  double microseconds () const
439  {return elapsed_ / (frequency_ * 1e-6);}
440 
441  double milliseconds () const
442  {return elapsed_ / (frequency_ * 1e-3);}
443 
444  double seconds () const
445  {return elapsed_ / static_cast<double>(frequency_);}
446 
447  double minutes () const
448  {return seconds() / 60;}
449 
450  double hours () const
451  {return seconds() / 3600;}
452 
453  private :
454 
455  __int64 elapsed_;
456  __int64 start_time_;
457  __int64 frequency_;
458  bool running_;
459 }; // class StopWatchSYS
460 
461 #endif // defined(VSMC_MACOSX)
462 
466 
467 } // namespace vsmc
468 
469 #endif // VSMC_UTILITY_STOP_WATCH_HPP
Definition: adapter.hpp:37
double minutes() const
Definition: stop_watch.hpp:108
bool running() const
Definition: stop_watch.hpp:99
::vsmc::StopWatchChrono StopWatch
The default StopWatch.
Definition: stop_watch.hpp:465
double seconds() const
Definition: stop_watch.hpp:107
#define VSMC_CONSTEXPR
constexpr
Definition: defines.hpp:55
double nanoseconds() const
Definition: stop_watch.hpp:284
double hours() const
Definition: stop_watch.hpp:109
double nanoseconds() const
Return the accumulated elapsed time in nanoseconds.
Definition: stop_watch.hpp:175
double microseconds() const
Definition: stop_watch.hpp:287
double hours() const
Return the accumulated elapsed time in hours.
Definition: stop_watch.hpp:210
void reset()
Stop and reset the elapsed time to zero.
Definition: stop_watch.hpp:167
double microseconds() const
Definition: stop_watch.hpp:105
double minutes() const
Definition: stop_watch.hpp:296
StopWatchGuard(watch_type &watch, bool start=true)
Definition: stop_watch.hpp:79
double minutes() const
Return the accumulated elapsed time in minutes.
Definition: stop_watch.hpp:203
double milliseconds() const
Definition: stop_watch.hpp:106
StopWatch as an adapter of C++11 clock.
Definition: stop_watch.hpp:117
bool stop()
Stop the watch, no effect if already stopped.
Definition: stop_watch.hpp:154
double microseconds() const
Return the accumulated elapsed time in microseconds.
Definition: stop_watch.hpp:182
double milliseconds() const
Return the accumulated elapsed time in milliseconds.
Definition: stop_watch.hpp:189
Stop watch using system native API.
Definition: stop_watch.hpp:238
#define VSMC_STOP_WATCH_TYPE
Default StopWatch type.
Definition: stop_watch.hpp:52
double milliseconds() const
Definition: stop_watch.hpp:290
A null StopWatch.
Definition: stop_watch.hpp:95
bool start()
Start the watch, no effect if already started.
Definition: stop_watch.hpp:138
double nanoseconds() const
Definition: stop_watch.hpp:104
Start and stop a StopWatch in scope (similiar to a mutex lock guard)
Definition: stop_watch.hpp:73
double hours() const
Definition: stop_watch.hpp:299
StopWatchClockAdapter< std::chrono::high_resolution_clock > StopWatchChrono
Stop watch using
Definition: stop_watch.hpp:226
double seconds() const
Definition: stop_watch.hpp:293
bool running() const
If the watch is running.
Definition: stop_watch.hpp:130
double seconds() const
Return the accumulated elapsed time in seconds.
Definition: stop_watch.hpp:196