Skip to content
Advertisement

Understanding the output of gettimeofday

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement