Stable high resolution timer on Linux
category: code [glöplog]
What timer function do you guys use for high resolution timer on Linux? I've tried clock_gettime which has a nanosec precision, but it seems like I am not handling it properly or it isn't stable. Any tips?
Are you using CLOCK_REALTIME or CLOCK_MONOTONIC?
CLOCK_REALTIME could be affected by things such as ntp synchronization.
Also, the clock most certainly does NOT have nanosecond precision. Nothing does, in any non-realtime OS.
On x86, the rdtsc instruction can give you a cheap and reliable high resolution timer.
The only problem is determining its frequency.
On early x86, it was a cycle counter, so if you just measured the delta of two rdtscs in a second, you knew the frequency.
Modern x86 have the tsc running at a fixed frequency (the rated frequency of the CPU, so different from one CPU to the next), while the actual CPU frequency can vary because of power saving/turbo boost.
Therefore you'd need a more reliable way to determine clockspeed (not sure how this is generally done, some OS libs may be available).
CLOCK_REALTIME could be affected by things such as ntp synchronization.
Also, the clock most certainly does NOT have nanosecond precision. Nothing does, in any non-realtime OS.
On x86, the rdtsc instruction can give you a cheap and reliable high resolution timer.
The only problem is determining its frequency.
On early x86, it was a cycle counter, so if you just measured the delta of two rdtscs in a second, you knew the frequency.
Modern x86 have the tsc running at a fixed frequency (the rated frequency of the CPU, so different from one CPU to the next), while the actual CPU frequency can vary because of power saving/turbo boost.
Therefore you'd need a more reliable way to determine clockspeed (not sure how this is generally done, some OS libs may be available).
I am using CLOCK_MONOTONIC.
The main issue here is that sometimes t0 is bigger than t.
Code:
timespec tgt;
clock_gettime(CLOCK_MONOTONIC,&tgt);
long long t0 = tgt.tv_nsec/1000/1000;
for (int i = 100000000; i; i--)
v1 += v1;
clock_gettime(CLOCK_MONOTONIC,&tgt);
long long t = tgt.tv_nsec/1000/1000;
std::cout << t0 << " " << t << " " << t-t0 << std::endl;
The main issue here is that sometimes t0 is bigger than t.
Hum, CLOCK_MONOTONIC should never have t0 > t by definition.
Sounds like a bug in the implementation. Perhaps you should try some live CDs with different distros/kernel versions?
This should never happen.
Sounds like a bug in the implementation. Perhaps you should try some live CDs with different distros/kernel versions?
This should never happen.
Oh wait. Shit. I am ignoring tv_sec.
You could also try CLOCK_MONOTONIC_RAW and see if that improves things.
Also, disable ntp if you have it running.
Also, disable ntp if you have it running.
I guess tv_nsec is just overflowing
Quote:
Oh wait. Shit. I am ignoring tv_sec.
Ah right, that explains it :)
In fact it isn't overflowing, it resets when it gets in 1 second.
Thanks anyway, the dialogue is always important haha :P
Thanks anyway, the dialogue is always important haha :P
clock_gettime using monotonic if I will be comparing the times with other outputs, time sources synced with PTP.
If local to the machine only, and timestamp doesn't matter, rdtsc tends to keep things moving along nicely if you're in a tightish loop.
If local to the machine only, and timestamp doesn't matter, rdtsc tends to keep things moving along nicely if you're in a tightish loop.