Skip to content

Instantly share code, notes, and snippets.

@hoxnox
Created May 26, 2023 13:36
Show Gist options
  • Save hoxnox/0ce61c17c70267995617f5e09985ceac to your computer and use it in GitHub Desktop.
Save hoxnox/0ce61c17c70267995617f5e09985ceac to your computer and use it in GitHub Desktop.
High speed timer
#pragma once
#include <ctime>
#include <cstdint>
#include <iostream>
#include <rte_cycles.h>
class HighSpeedTimer {
public:
std::uint64_t
nanoseconds_since_epoch()
{
auto cur_tsc = rdtsc();
uint64_t rs{};
if (cur_tsc - prev_tsc_ > 20'000 || cur_tsc < prev_prev_tsc_ || prev_prev_ts_.tv_sec == 0)
{
prev_prev_tsc_ = prev_tsc_;
prev_prev_ts_ = prev_ts_;
clock_gettime(CLOCK_REALTIME, &prev_ts_);
prev_tsc_ = cur_tsc;
cycle_duration = float((prev_ts_.tv_sec - prev_prev_ts_.tv_sec)*1'000'000'000
+ (prev_ts_.tv_nsec - prev_prev_ts_.tv_nsec))/(prev_tsc_ - prev_prev_tsc_);
rs = prev_ts_.tv_sec * 1'000'000'000;
rs += prev_ts_.tv_nsec;
}
else
{
rs = prev_ts_.tv_sec*1'000'000'000;
rs += prev_ts_.tv_nsec;
rs += (uint64_t)(cycle_duration*(cur_tsc - prev_tsc_));
}
return rs;
}
private:
uint64_t rdtsc() {
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
} tsc;
asm volatile("rdtsc" : "=a" (tsc.lo_32), "=d" (tsc.hi_32));
return tsc.tsc_64;
}
uint64_t prev_tsc_{};
uint64_t prev_prev_tsc_{};
struct timespec prev_ts_{};
struct timespec prev_prev_ts_{};
float cycle_duration{};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment