Agora  1.2.0
Agora project
gettime.h
Go to the documentation of this file.
1 
6 #ifndef GETTIME_INC_
7 #define GETTIME_INC_
8 
9 #include "symbols.h"
10 
11 namespace GetTime {
12 
13 // Get current time in microseconds
14 static inline double GetTimeUs() {
15  struct timespec tv;
16  clock_gettime(CLOCK_MONOTONIC, &tv);
17  return tv.tv_sec * 1000000 + tv.tv_nsec / 1000.0;
18 }
19 
20 // Get current time in microseconds. This can be deleted after we replace
21 // all occurences of get_time() with get_time_us()
22 static inline double GetTime() { return GetTimeUs(); }
23 
25 static inline size_t Rdtsc() {
26  uint64_t rax;
27  uint64_t rdx;
28  asm volatile("rdtsc" : "=a"(rax), "=d"(rdx));
29  return static_cast<size_t>((rdx << 32) | rax);
30 }
31 
34 static inline size_t WorkerRdtsc() {
35  return kIsWorkerTimingEnabled ? Rdtsc() : 0;
36 }
37 
39 static inline void NanoSleep(size_t ns, double freq_ghz) {
40  size_t start = Rdtsc();
41  size_t end = start;
42  auto upp = static_cast<size_t>(freq_ghz * ns);
43  while (end - start < upp) {
44  end = Rdtsc();
45  }
46 }
47 
51 static inline double MeasureRdtscFreq() {
52  struct timespec start;
53  struct timespec end;
54  clock_gettime(CLOCK_REALTIME, &start);
55  uint64_t rdtsc_start = Rdtsc();
56 
57  // Do not change this loop! The hardcoded value below depends on this
58  // loop and prevents it from being optimized out.
59  uint64_t sum = 5;
60  for (uint64_t i = 0; i < 1000000; i++) {
61  sum += i + (sum + i) * (i % sum);
62  }
63  if (sum != 13580802877818827968ull) {
64  std::printf("Error in RDTSC freq measurement");
65  throw std::runtime_error("Error in RDTSC freq measurement");
66  }
67 
68  clock_gettime(CLOCK_REALTIME, &end);
69  uint64_t clock_ns =
70  static_cast<uint64_t>(end.tv_sec - start.tv_sec) * 1000000000 +
71  static_cast<uint64_t>(end.tv_nsec - start.tv_nsec);
72  uint64_t rdtsc_cycles = GetTime::Rdtsc() - rdtsc_start;
73 
74  double freq_ghz = rdtsc_cycles * 1.0 / clock_ns;
75 
76  // RDTSC frequencies outside these ranges are rare
77  if (freq_ghz < 1.0 && freq_ghz > 4.0) {
78  std::printf("Invalid RDTSC frequency %.2f\n", freq_ghz);
79  throw std::runtime_error("Invalid RDTSC frequency");
80  }
81  return freq_ghz;
82 }
83 
85 static inline double CyclesToSec(size_t cycles, double freq_ghz) {
86  return (cycles / (freq_ghz * 1000000000));
87 }
88 
91 static inline double CyclesToMs(size_t cycles, double freq_ghz) {
92  return (cycles / (freq_ghz * 1000000));
93 }
94 
97 static inline double CyclesToUs(size_t cycles, double freq_ghz) {
98  return (cycles / (freq_ghz * 1000));
99 }
100 
103 static inline double CyclesToNs(size_t cycles, double freq_ghz) {
104  return (cycles / freq_ghz);
105 }
106 
107 static inline size_t MsToCycles(double ms, double freq_ghz) {
108  return static_cast<size_t>(ms * 1000 * 1000 * freq_ghz);
109 }
110 
111 static inline size_t UsToCycles(double us, double freq_ghz) {
112  return static_cast<size_t>(us * 1000 * freq_ghz);
113 }
114 
115 static inline size_t NsToCycles(double ns, double freq_ghz) {
116  return static_cast<size_t>(ns * freq_ghz);
117 }
118 
120 static inline double SecSince(const struct timespec& t0) {
121  struct timespec t1;
122  clock_gettime(CLOCK_REALTIME, &t1);
123  return (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1000000000.0;
124 }
125 
127 static inline double NsSince(const struct timespec& t0) {
128  struct timespec t1;
129  clock_gettime(CLOCK_REALTIME, &t1);
130  return (t1.tv_sec - t0.tv_sec) * 1000000000.0 + (t1.tv_nsec - t0.tv_nsec);
131 }
132 
133 }; // end namespace GetTime
134 
135 #endif // GETTIME_INC_
freq_ghz
double freq_ghz
Definition: bench.cc:10
fmt::v8::printf
auto printf(const S &fmt, const T &... args) -> int
Definition: printf.h:631
GetTime::CyclesToNs
static double CyclesToNs(size_t cycles, double freq_ghz)
Definition: gettime.h:103
GetTime::MsToCycles
static size_t MsToCycles(double ms, double freq_ghz)
Definition: gettime.h:107
GetTime::NsSince
static double NsSince(const struct timespec &t0)
Return nanoseconds elapsed since timestamp t0.
Definition: gettime.h:127
GetTime::GetTimeUs
static double GetTimeUs()
Definition: gettime.h:14
GetTime::UsToCycles
static size_t UsToCycles(double us, double freq_ghz)
Definition: gettime.h:111
GetTime::CyclesToUs
static double CyclesToUs(size_t cycles, double freq_ghz)
Definition: gettime.h:97
i
for i
Definition: generate_data.m:107
GetTime
Definition: gettime.h:11
GetTime::NanoSleep
static void NanoSleep(size_t ns, double freq_ghz)
Sleep for some nanoseconds.
Definition: gettime.h:39
GetTime::Rdtsc
static size_t Rdtsc()
Return the TSC.
Definition: gettime.h:25
GetTime::SecSince
static double SecSince(const struct timespec &t0)
Return seconds elapsed since timestamp t0.
Definition: gettime.h:120
start
end start
Definition: inspect_agora_results.m:95
GetTime::CyclesToSec
static double CyclesToSec(size_t cycles, double freq_ghz)
Convert cycles measured by rdtsc with frequence freq_ghz to seconds.
Definition: gettime.h:85
symbols.h
kIsWorkerTimingEnabled
static constexpr bool kIsWorkerTimingEnabled
Definition: symbols.h:303
GetTime::NsToCycles
static size_t NsToCycles(double ns, double freq_ghz)
Definition: gettime.h:115
GetTime::MeasureRdtscFreq
static double MeasureRdtscFreq()
Definition: gettime.h:51
GetTime::GetTime
static double GetTime()
Definition: gettime.h:22
GetTime::WorkerRdtsc
static size_t WorkerRdtsc()
Definition: gettime.h:34
GetTime::CyclesToMs
static double CyclesToMs(size_t cycles, double freq_ghz)
Definition: gettime.h:91
nlohmann::json_v3_11_1NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON::detail2::end
end_tag end(T &&...)