1 #ifndef KMP_STATS_TIMING_H
2 #define KMP_STATS_TIMING_H
4 /** @file kmp_stats_timing.h
5 * Access to real time clock and timers.
8 //===----------------------------------------------------------------------===//
10 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://llvm.org/LICENSE.txt for license information.
12 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //===----------------------------------------------------------------------===//
20 #if KMP_HAVE_X86INTRIN_H
21 #include <x86intrin.h>
24 class tsc_tick_count
{
29 class tsc_interval_t
{
31 explicit tsc_interval_t(int64_t _value
) : value(_value
) {}
34 tsc_interval_t() : value(0) {} // Construct 0 time duration
35 #if KMP_HAVE_TICK_TIME
36 double seconds() const; // Return the length of a time interval in seconds
38 double ticks() const { return double(value
); }
39 int64_t getValue() const { return value
; }
40 tsc_interval_t
&operator=(int64_t nvalue
) {
45 friend class tsc_tick_count
;
47 friend tsc_interval_t
operator-(const tsc_tick_count
&t1
,
48 const tsc_tick_count
&t0
);
49 friend tsc_interval_t
operator-(const tsc_tick_count::tsc_interval_t
&i1
,
50 const tsc_tick_count::tsc_interval_t
&i0
);
51 friend tsc_interval_t
&operator+=(tsc_tick_count::tsc_interval_t
&i1
,
52 const tsc_tick_count::tsc_interval_t
&i0
);
55 #if KMP_HAVE___BUILTIN_READCYCLECOUNTER
57 : my_count(static_cast<int64_t>(__builtin_readcyclecounter())) {}
58 #elif KMP_HAVE___RDTSC
59 tsc_tick_count() : my_count(static_cast<int64_t>(__rdtsc())) {}
61 #error Must have high resolution timer defined
63 tsc_tick_count(int64_t value
) : my_count(value
) {}
64 int64_t getValue() const { return my_count
; }
65 tsc_tick_count
later(tsc_tick_count
const other
) const {
66 return my_count
> other
.my_count
? (*this) : other
;
68 tsc_tick_count
earlier(tsc_tick_count
const other
) const {
69 return my_count
< other
.my_count
? (*this) : other
;
71 #if KMP_HAVE_TICK_TIME
72 static double tick_time(); // returns seconds per cycle (period) of clock
74 static tsc_tick_count
now() {
75 return tsc_tick_count();
76 } // returns the rdtsc register value
77 friend tsc_tick_count::tsc_interval_t
operator-(const tsc_tick_count
&t1
,
78 const tsc_tick_count
&t0
);
81 inline tsc_tick_count::tsc_interval_t
operator-(const tsc_tick_count
&t1
,
82 const tsc_tick_count
&t0
) {
83 return tsc_tick_count::tsc_interval_t(t1
.my_count
- t0
.my_count
);
86 inline tsc_tick_count::tsc_interval_t
87 operator-(const tsc_tick_count::tsc_interval_t
&i1
,
88 const tsc_tick_count::tsc_interval_t
&i0
) {
89 return tsc_tick_count::tsc_interval_t(i1
.value
- i0
.value
);
92 inline tsc_tick_count::tsc_interval_t
&
93 operator+=(tsc_tick_count::tsc_interval_t
&i1
,
94 const tsc_tick_count::tsc_interval_t
&i0
) {
99 #if KMP_HAVE_TICK_TIME
100 inline double tsc_tick_count::tsc_interval_t::seconds() const {
101 return value
* tick_time();
105 extern std::string
formatSI(double interval
, int width
, char unit
);
107 inline std::string
formatSeconds(double interval
, int width
) {
108 return formatSI(interval
, width
, 'S');
111 inline std::string
formatTicks(double interval
, int width
) {
112 return formatSI(interval
, width
, 'T');
115 #endif // KMP_STATS_TIMING_H