14 # error "<Gaudi/Timers/RdtscClock.h> is only supported on x86"
15 #else // not __x86_64__
18 # include <functional>
21 # include <x86intrin.h>
36 template <
typename Precision = std::chrono::microseconds>
40 typedef typename Precision::rep rep;
41 typedef typename Precision::period period;
42 typedef std::chrono::duration<rep, period> duration;
43 typedef std::chrono::time_point<RdtscClock> time_point;
45 static constexpr
bool is_steady{
true };
48 static_assert( period::num == 1,
"The Precision of RdtscClock must be reducible to 1/N" );
49 static_assert( std::ratio_less_equal<period, std::milli>(),
50 "The Precision of RdtscClock must be at least std::chrono::milliseconds" );
53 static rep calibrate() noexcept {
return ticks_per_unit(); }
55 static time_point now() noexcept {
return time_point{ duration( __rdtsc() / ticks_per_unit() ) }; }
58 static rep ticks_per_unit() noexcept {
59 static rep ticks_per_unit = do_calibrate();
60 return ticks_per_unit;
63 static rep do_calibrate() noexcept {
65 static constexpr
auto calibTime = std::chrono::milliseconds( 100 );
66 static constexpr
auto toPrec = std::ratio_divide<std::milli, period>::num;
69 auto t1_ref = std::chrono::high_resolution_clock::now();
71 std::this_thread::sleep_for( calibTime );
73 auto t2_ref = std::chrono::high_resolution_clock::now();
76 auto dt_ref = std::chrono::duration_cast<std::chrono::milliseconds>( t2_ref - t1_ref ).count();
77 rep ticks_per_unit = (
t2 -
t1 ) / ( dt_ref * toPrec );
79 return ticks_per_unit;