The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
RdtscClock.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#pragma once
12
13#ifndef __x86_64__
14# error "<Gaudi/Timers/RdtscClock.h> is only supported on x86"
15#else // not __x86_64__
16
17# include <chrono>
18# include <functional>
19# include <ratio>
20# include <thread>
21# include <x86intrin.h>
22
23namespace Gaudi {
24 namespace Timers {
36 template <typename Precision = std::chrono::microseconds>
37 class RdtscClock {
38 public:
39 // to meet requirements of TrivialClock:
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;
44
45 static constexpr bool is_steady{ true };
46
47 // some sanity checks:
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" );
51
53 static rep calibrate() noexcept { return ticks_per_unit(); }
54
55 static time_point now() noexcept { return time_point{ duration( __rdtsc() / ticks_per_unit() ) }; }
56
57 private:
58 static rep ticks_per_unit() noexcept {
59 static rep ticks_per_unit = do_calibrate(); // local static guarantees thread-safety
60 return ticks_per_unit;
61 }
62
63 static rep do_calibrate() noexcept {
64 // Calibration time and conversion factor to unit of Precision
65 static constexpr auto calibTime = std::chrono::milliseconds( 100 );
66 static constexpr auto toPrec = std::ratio_divide<std::milli, period>::num;
67
68 // Calibrate against wall clock
69 auto t1_ref = std::chrono::high_resolution_clock::now();
70 auto t1 = __rdtsc();
71 std::this_thread::sleep_for( calibTime );
72 auto t2 = __rdtsc();
73 auto t2_ref = std::chrono::high_resolution_clock::now();
74
75 // Calculate ticks per unit of Precision
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 );
78
79 return ticks_per_unit;
80 }
81 };
82 } // namespace Timers
83} // namespace Gaudi
84#endif
TemplatedAlg< int, std::vector< std::string > > t1
TemplatedAlg< double, bool > t2
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1