vSMC
vSMC: Scalable Monte Carlo
rdtsc.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/utility/rdtsc.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_RDTSC_HPP
33 #define VSMC_UTILITY_RDTSC_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #ifdef VSMC_MSVC
38 #include <intrin.h>
39 #endif
40 
41 namespace vsmc {
42 
48 inline uint64_t rdtsc ()
49 {
50 #ifdef VSMC_MSVC
51  return static_cast<uint64_t>(__rdtsc());
52 #else // VSMC_MSVC
53  unsigned eax = 0;
54  unsigned edx = 0;
55  __asm__ volatile
56  (
57  "rdtsc\n"
58  : "=a" (eax), "=d" (edx)
59  );
60 
61  return (static_cast<uint64_t>(edx) << 32) + static_cast<uint64_t>(eax);
62 #endif // VSMC_MSVC
63 }
64 
67 inline uint64_t rdtscp (unsigned *aux)
68 {
69 #ifdef VSMC_MSVC
70  return static_cast<uint64_t>(__rdtscp(aux));
71 #else // VSMC_MSVC
72  unsigned eax = 0;
73  unsigned ecx = 0;
74  unsigned edx = 0;
75  __asm__ volatile
76  (
77  "rdtscp\n"
78  : "=a" (eax), "=c" (ecx), "=d" (edx)
79  );
80  *aux = ecx;
81 
82  return static_cast<uint64_t>(eax) + (static_cast<uint64_t>(edx) << 32);
83 #endif // VSMC_MSVC
84 }
85 
89 {
90  public :
91 
92  RDTSCCounter () : elapsed_(0), start_(0), running_(false) {}
93 
99  bool running () const {return running_;}
100 
107  bool start ()
108  {
109  if (running_)
110  return false;
111 
112  running_ = true;
113  start_ = rdtsc();
114 
115  return true;
116  }
117 
127  bool stop ()
128  {
129  if (!running_)
130  return false;
131 
132  uint64_t stop = rdtsc();
133  if (stop < start_)
134  return false;
135 
136  elapsed_ += stop - start_;
137  running_ = false;
138 
139  return true;
140  }
141 
143  void reset ()
144  {
145  elapsed_ = 0;
146  running_ = false;
147  }
148 
150  uint64_t cycles () const {return elapsed_;}
151 
152  private :
153 
154  uint64_t elapsed_;
155  uint64_t start_;
156  bool running_;
157 }; // class RDTSCCounter
158 
170 {
171  public :
172 
173  RDTSCPCounter () : elapsed_(0), start_(0), start_id_(0), running_(false) {}
174 
180  bool running () const {return running_;}
181 
188  bool start ()
189  {
190  if (running_)
191  return false;
192 
193  running_ = true;
194  start_ = rdtscp(&start_id_);
195 
196  return true;
197  }
198 
210  bool stop ()
211  {
212  if (!running_)
213  return false;
214 
215  unsigned stop_id = 0;
216  uint64_t stop = rdtscp(&stop_id);
217  if (stop_id != start_id_ || stop < start_)
218  return false;
219 
220  elapsed_ += stop - start_;
221  running_ = false;
222 
223  return true;
224  }
225 
227  void reset ()
228  {
229  elapsed_ = 0;
230  running_ = false;
231  }
232 
234  uint64_t cycles () const {return elapsed_;}
235 
236  private :
237 
238  uint64_t elapsed_;
239  uint64_t start_;
240  unsigned start_id_;
241  bool running_;
242 }; // class RDTSCPCounter
243 
244 } // namespace vsmc
245 
246 #endif // VSMC_UTILITY_RDTSC_HPP
Definition: adapter.hpp:37
bool running() const
If the counter is running.
Definition: rdtsc.hpp:99
void reset()
Stop and reset the elapsed cycle count to zero.
Definition: rdtsc.hpp:227
bool running() const
If the counter is running.
Definition: rdtsc.hpp:180
CPU clock cycle counter using rdtsc
Definition: rdtsc.hpp:88
uint64_t cycles() const
Return the accumulated elapsed cycle count.
Definition: rdtsc.hpp:234
bool stop()
Stop the counter, no effect if already stopped.
Definition: rdtsc.hpp:210
bool start()
Start the counter, no effect if already started.
Definition: rdtsc.hpp:107
uint64_t rdtsc()
Return the TSC value using RDTSC instruction.
Definition: rdtsc.hpp:48
bool stop()
Stop the counter, no effect if already stopped.
Definition: rdtsc.hpp:127
uint64_t cycles() const
Return the accumulated elapsed cycle count.
Definition: rdtsc.hpp:150
bool start()
Start the counter, no effect if already started.
Definition: rdtsc.hpp:188
CPU clock cycle counter using rdtscp
Definition: rdtsc.hpp:169
uint64_t rdtscp(unsigned *aux)
Return the TSC and TSC_AUX values using RDTSCP instruction.
Definition: rdtsc.hpp:67
void reset()
Stop and reset the elapsed cycle count to zero.
Definition: rdtsc.hpp:143