| The Gaudi Framework v32r1 (f65d50dc)

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;
28 typedef std::chrono::duration<rep, period> duration;
29 typedef std::chrono::time_point<RdtscClock> time_point;
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" );
35 static_assert( std::ratio_less_equal<period, std::milli>(),
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
55 auto t1_ref = std::chrono::high_resolution_clock::now();
56 auto t1 = __rdtsc();
57 std::this_thread::sleep_for( calibTime );
58 auto t2 = __rdtsc();
59 auto t2_ref = std::chrono::high_resolution_clock::now();
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
std::chrono::duration
Gaudi::Timers::RdtscClock::rep
Precision::rep rep
Definition: RdtscClock.h:26
Gaudi::Timers::RdtscClock::do_calibrate
static rep do_calibrate() noexcept
Definition: RdtscClock.h:49
Gaudi::Timers::RdtscClock::ticks_per_unit
static rep ticks_per_unit() noexcept
Definition: RdtscClock.h:44
std::this_thread::sleep_for
T sleep_for(T... args)
Gaudi::Timers::RdtscClock::calibrate
static rep calibrate() noexcept
Calibrate the RDTSC clock against wall time.
Definition: RdtscClock.h:39
Gaudi::Timers::RdtscClock::now
static time_point now() noexcept
Definition: RdtscClock.h:41
Gaudi::Timers::RdtscClock
A std::chrono compatible Clock using rdtsc as its timing source.
Definition: RdtscClock.h:23
Gaudi::Timers::RdtscClock::duration
std::chrono::duration< rep, period > duration
Definition: RdtscClock.h:28
Gaudi::Timers::RdtscClock::period
Precision::period period
Definition: RdtscClock.h:27
Gaudi::Timers::RdtscClock::time_point
std::chrono::time_point< RdtscClock > time_point
Definition: RdtscClock.h:29
Gaudi::Timers::RdtscClock::is_steady
static constexpr bool is_steady
Definition: RdtscClock.h:31
std::chrono::high_resolution_clock::now
T now(T... args)
std::chrono::time_point
std::ratio_divide
std::ratio_less_equal
Gaudi
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1