I am trying to understand the precision of the gettimeofday()
system call. Here’s my program:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/time.h> int main(int argc, char *argv[]) { struct timeval t; int prev = 0; for (int i = 0; i < atoi(argv[1]); i++) { gettimeofday(&t, NULL); printf("secs: %ld, nmicro_secs: %d, delta: %dn", t.tv_sec, t.tv_usec, t.tv_usec - prev); prev = t.tv_usec; sleep(1); } return 0; }
The output if I run this program (./a.out 10
) is,
secs: 1643494972, nmicro_secs: 485698, delta: 485698 secs: 1643494973, nmicro_secs: 490785, delta: 5087 secs: 1643494974, nmicro_secs: 491121, delta: 336 secs: 1643494975, nmicro_secs: 494810, delta: 3689 secs: 1643494976, nmicro_secs: 500034, delta: 5224 secs: 1643494977, nmicro_secs: 501143, delta: 1109 secs: 1643494978, nmicro_secs: 506397, delta: 5254 secs: 1643494979, nmicro_secs: 509905, delta: 3508 secs: 1643494980, nmicro_secs: 510637, delta: 732 secs: 1643494981, nmicro_secs: 513451, delta: 2814
The seconds column seems to reconcile with the sleep of 1 secs. Can someone please explain what’s going on with the values in micro seconds column? It looks like the jumps from sleep to sleep are ~ 1 millisecond.
Advertisement
Answer
You are calculating the difference between two consecutive calls only using the .tv_usec
field. In other words, you are discarding the .tv_sec
field, and therefore if the first measurement yields .tv_sec=1, .tv_usec=500000
(meaning 1.5s since epoch) and the second one yields .tv_sec=2, .tv_usec=500000
(meaning 2.5s since epoch) your delta
would be exactly 0
, which is wrong.
You have to take into account the entire value: t.tv_sec * 1000000 + t.tv_usec
. Only then you can calculate a meaningful difference. Note that you will need a type larger than int
to hold this value. Something like uintmax_t
should be adequate. Or, as @zwol suggests in the comments, two different struct timeval
if you want to calculate the difference without an intermediate type.
I am trying to understand the precision of the
gettimeofday()
system call
In any case, none of what you are doing will tell you the precision of gettimeofday
, which is a different thing. Sleeping between two syscalls will make your process inactive for a not-so-deterministic amount of time.