Hey there... Recently I saw this code in divan codebase:
|
pub fn precision(self) -> FineDuration { |
|
static CACHED: [OnceLock<FineDuration>; Timer::COUNT] = |
|
[OnceLock::new(), OnceLock::new()]; |
|
|
|
let cached = &CACHED[self.kind() as usize]; |
|
|
|
*cached.get_or_init(|| self.measure_precision()) |
Just wanted to share that there is no need to measure system timer precision, it can be queried from the OS. Modern OSes use rdtscp/cntvct for keeping track of time, and in order to convert counter value to an absolute time they need timer precision.
On macOS this can be solved by
#include <mach/mach_time.h>
#include <stdint.h>
#include <stdio.h>
int main(void) {
mach_timebase_info_data_t info;
mach_timebase_info(&info);
printf("numer = %u, denom = %u\n", info.numer, info.denom);
return 0;
}
On my machine it outputs numer = 125, denom = 3, which basically means that in order to convert cntvct_el0 value from ticks to nanoseconds you need to multiply by 125 and then divide by 3. So system timer is running at exactly 24MHz or 41.6(6)ns.
On Linux there is clock_getres(), pretty sure there is something similar on Windows.
Cheers!
Hey there... Recently I saw this code in divan codebase:
divan/src/time/timer.rs
Lines 55 to 61 in bca5c96
Just wanted to share that there is no need to measure system timer precision, it can be queried from the OS. Modern OSes use
rdtscp/cntvctfor keeping track of time, and in order to convert counter value to an absolute time they need timer precision.On macOS this can be solved by
On my machine it outputs
numer = 125, denom = 3, which basically means that in order to convertcntvct_el0value from ticks to nanoseconds you need to multiply by 125 and then divide by 3. So system timer is running at exactly 24MHz or 41.6(6)ns.On Linux there is
clock_getres(), pretty sure there is something similar on Windows.Cheers!