vSMC  v3.0.0
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-2016, 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 #ifdef VSMC_MSVC
38 #include <intrin.h>
39 #endif
40 
43 #ifndef VSMC_STOP_WATCH_CLOCK_TYPE
44 #define VSMC_STOP_WATCH_CLOCK_TYPE std::chrono::high_resolution_clock
45 #endif
46 
47 namespace vsmc
48 {
49 
50 namespace internal
51 {
52 
54 {
55 #if VSMC_HAS_X86
56 
57 #if defined(VSMC_CLANG) || defined(VSMC_GCC) || defined(VSMC_INTEL)
58  unsigned hi = 0;
59  unsigned lo = 0;
60 #if VSMC_HAS_X86_64
61  asm volatile("CPUID\n\t"
62  "RDTSC\n\t"
63  "mov %%edx, %0\n\t"
64  "mov %%eax, %1\n\t"
65  : "=r"(hi), "=r"(lo)::"%rax", "%rbx", "%rcx", "%rdx");
66 #else // VSMC_HAS_X64_64
67  asm volatile("CPUID\n\t"
68  "RDTSC\n\t"
69  "mov %%edx, %0\n\t"
70  "mov %%eax, %1\n\t"
71  : "=r"(lo), "=r"(lo)::"%eax", "%ebx", "%ecx", "%edx");
72 #endif // VSMC_HAS_X86_64
73  return (static_cast<std::uint64_t>(hi) << 32) + lo;
74 #elif defined(VSMC_MSVC)
75  return static_cast<std::uint64_t>(__rdtsc());
76 #else // defined(VSMC_CLANG) || defined(VSMC_GCC) || defined(VSMC_INTEL)
77  return 0;
78 #endif // defined(VSMC_CLANG) || defined(VSMC_GCC) || defined(VSMC_INTEL)
79 
80 #else // VSMC_HAS_X86
81  return 0;
82 #endif // VSMC_HAS_X86
83 }
84 
85 } // namespace vsmc::internal
86 
90 template <typename WatchType>
92 {
93  public:
94  using watch_type = WatchType;
95 
96  StopWatchGuard(watch_type &watch, bool start = true)
97  : start_(start), watch_(watch)
98  {
99  if (start_)
100  watch_.start();
101  }
102 
104  {
105  if (start_)
106  watch_.stop();
107  }
108 
109  private:
110  const bool start_;
111  watch_type &watch_;
112 }; // class StopWatchGuard
113 
116 template <typename ClockType>
118 {
119  public:
120  using clock_type = ClockType;
121 
123  : time_(0), cycles_(0), cycles_start_(0), running_(false)
124  {
125  reset();
126  }
127 
133  bool running() const { return running_; }
134 
141  bool start()
142  {
143  if (running_)
144  return false;
145 
146  running_ = true;
147  time_start_ = clock_type::now();
148  cycles_start_ = internal::rdtsc();
149 
150  return true;
151  }
152 
158  bool stop()
159  {
160  if (!running_)
161  return false;
162 
163  cycles_ += static_cast<double>(internal::rdtsc() - cycles_start_);
164  typename clock_type::time_point time_stop = clock_type::now();
165  time_ += time_stop - time_start_;
166  running_ = false;
167 
168  return true;
169  }
170 
172  void reset()
173  {
174  start();
175  time_ = typename clock_type::duration(0);
176  cycles_ = 0;
177  running_ = false;
178  }
179 
181  double cycles() const { return cycles_; }
182 
184  double nanoseconds() const
185  {
186  return std::chrono::duration_cast<
187  std::chrono::duration<double, std::nano>>(time_)
188  .count();
189  }
190 
192  double microseconds() const
193  {
194  return std::chrono::duration_cast<
195  std::chrono::duration<double, std::micro>>(time_)
196  .count();
197  }
198 
200  double milliseconds() const
201  {
202  return std::chrono::duration_cast<
203  std::chrono::duration<double, std::milli>>(time_)
204  .count();
205  }
206 
208  double seconds() const
209  {
210  return std::chrono::duration_cast<
211  std::chrono::duration<double, std::ratio<1>>>(time_)
212  .count();
213  }
214 
216  double minutes() const
217  {
218  return std::chrono::duration_cast<
219  std::chrono::duration<double, std::ratio<60>>>(time_)
220  .count();
221  }
222 
224  double hours() const
225  {
226  return std::chrono::duration_cast<
227  std::chrono::duration<double, std::ratio<3600>>>(time_)
228  .count();
229  }
230 
231  private:
232  typename clock_type::duration time_;
233  typename clock_type::time_point time_start_;
234  double cycles_;
235  std::uint64_t cycles_start_;
236  bool running_;
237 }; // class StopWatchClockAdapter
238 
242 
243 } // namespace vsmc
244 
245 #endif // VSMC_UTILITY_STOP_WATCH_HPP
Definition: monitor.hpp:48
ulong uint64_t
Definition: opencl.h:42
double cycles() const
Return the accumulated cycles.
Definition: stop_watch.hpp:181
double nanoseconds() const
Return the accumulated elapsed time in nanoseconds.
Definition: stop_watch.hpp:184
double hours() const
Return the accumulated elapsed time in hours.
Definition: stop_watch.hpp:224
void reset()
Stop and reset the elapsed time to zero.
Definition: stop_watch.hpp:172
StopWatchGuard(watch_type &watch, bool start=true)
Definition: stop_watch.hpp:96
double minutes() const
Return the accumulated elapsed time in minutes.
Definition: stop_watch.hpp:216
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:158
double microseconds() const
Return the accumulated elapsed time in microseconds.
Definition: stop_watch.hpp:192
std::uint64_t rdtsc()
Definition: stop_watch.hpp:53
double milliseconds() const
Return the accumulated elapsed time in milliseconds.
Definition: stop_watch.hpp:200
bool start()
Start the watch, no effect if already started.
Definition: stop_watch.hpp:141
Start and stop a StopWatch in scope (similiar to a mutex lock guard)
Definition: stop_watch.hpp:91
bool running() const
If the watch is running.
Definition: stop_watch.hpp:133
double seconds() const
Return the accumulated elapsed time in seconds.
Definition: stop_watch.hpp:208