The Gaudi Framework  v32r2 (46d42edc)
RdtscClock.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <chrono>
4 #include <functional>
5 #include <ratio>
6 #include <thread>
7 #include <x86intrin.h>
8 
9 namespace Gaudi {
10  namespace Timers {
22  template <typename Precision = std::chrono::microseconds>
23  class RdtscClock {
24  public:
25  // to meet requirements of TrivialClock:
26  typedef typename Precision::rep rep;
27  typedef typename Precision::period period;
30 
31  static constexpr bool is_steady{true};
32 
33  // some sanity checks:
34  static_assert( period::num == 1, "The Precision of RdtscClock must be reducible to 1/N" );
36  "The Precision of RdtscClock must be at least std::chrono::milliseconds" );
37 
39  static rep calibrate() noexcept { return ticks_per_unit(); }
40 
41  static time_point now() noexcept { return time_point{duration( __rdtsc() / ticks_per_unit() )}; }
42 
43  private:
44  static rep ticks_per_unit() noexcept {
45  static rep ticks_per_unit = do_calibrate(); // local static guarantees thread-safety
46  return ticks_per_unit;
47  }
48 
49  static rep do_calibrate() noexcept {
50  // Calibration time and conversion factor to unit of Precision
51  static constexpr auto calibTime = std::chrono::milliseconds( 100 );
52  static constexpr auto toPrec = std::ratio_divide<std::milli, period>::num;
53 
54  // Calibrate against wall clock
56  auto t1 = __rdtsc();
57  std::this_thread::sleep_for( calibTime );
58  auto t2 = __rdtsc();
60 
61  // Calculate ticks per unit of Precision
62  auto dt_ref = std::chrono::duration_cast<std::chrono::milliseconds>( t2_ref - t1_ref ).count();
63  rep ticks_per_unit = ( t2 - t1 ) / ( dt_ref * toPrec );
64 
65  return ticks_per_unit;
66  }
67  };
68  } // namespace Timers
69 } // namespace Gaudi
Precision::rep rep
Definition: RdtscClock.h:26
static rep do_calibrate() noexcept
Definition: RdtscClock.h:49
static rep ticks_per_unit() noexcept
Definition: RdtscClock.h:44
T sleep_for(T... args)
static rep calibrate() noexcept
Calibrate the RDTSC clock against wall time.
Definition: RdtscClock.h:39
static time_point now() noexcept
Definition: RdtscClock.h:41
A std::chrono compatible Clock using rdtsc as its timing source.
Definition: RdtscClock.h:23
std::chrono::duration< rep, period > duration
Definition: RdtscClock.h:28
Precision::period period
Definition: RdtscClock.h:27
std::chrono::time_point< RdtscClock > time_point
Definition: RdtscClock.h:29
static constexpr bool is_steady
Definition: RdtscClock.h:31
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1