diff --git a/haversine_02/include/profiler/timer.h b/haversine_02/include/profiler/timer.h new file mode 100644 index 0000000..93face6 --- /dev/null +++ b/haversine_02/include/profiler/timer.h @@ -0,0 +1,25 @@ +#ifndef TIMER_H +#define TIMER_H + +#include "aliases.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u64 get_os_frequency(); + +// Time in nanoseconds +u64 get_os_time(void); + +// CPU timer using rdtsc +u64 read_cpu_timer(void); + +// CPU frequency in hz/sec +u64 get_cpu_freq(u64 milliseconds); + +#ifdef __cplusplus +} +#endif + +#endif // !TIMER_H diff --git a/haversine_02/src/profiler/timer.c b/haversine_02/src/profiler/timer.c new file mode 100644 index 0000000..f4a8880 --- /dev/null +++ b/haversine_02/src/profiler/timer.c @@ -0,0 +1,46 @@ +#include "profiler/timer.h" +#include "aliases.h" +#include + +#include + +typedef struct timespec timespec_t; + +u64 get_os_frequency() { return 1000000000; } + +u64 get_os_time(void) { + timespec_t ts = {0}; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) { + return 0; + } + + return ts.tv_sec * get_os_frequency() + ts.tv_nsec; +} + +u64 read_cpu_timer(void) { return __rdtsc(); } + +u64 get_cpu_freq(u64 milliseconds) { + u64 os_freq = get_os_frequency(); + u64 os_start = get_os_time(); + u64 cpu_start = read_cpu_timer(); + u64 os_end = 0; + u64 os_elapsed = 0; + u64 os_wait_time = os_freq * milliseconds / 1000; + + while (os_elapsed < os_wait_time) { + os_end = get_os_time(); + os_elapsed = os_end - os_start; + } + + u64 cpu_end = read_cpu_timer(); + u64 cpu_elapsed = cpu_end - cpu_start; + + u64 cpu_freq = 0; + + if (os_elapsed) { + cpu_freq = cpu_elapsed * os_freq / os_elapsed; + } + + return cpu_freq; +}