cgettimeofday

Why the 2nd diff is so different from the others, using gettimeofday in a loop?


This function is quite new for me, so I just writed a little program to get familiar with it. Here's a my program (just printing laps between several calls of gettimeofday).

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>

typedef struct timeval t_timeval;

t_timeval    get_diff(t_timeval prev)
{
    t_timeval current_time;
    gettimeofday(&current_time, NULL);
    printf("diff : %ld seconds and %ld micro seconds\n",
        current_time.tv_sec - prev.tv_sec, current_time.tv_usec - prev.tv_usec);
    return (current_time);
}

int        get_time_laps()
{
    int            i = 0;
    t_timeval    prev;

    gettimeofday(&prev, NULL);
    while (i++ < 50)
        prev = get_diff(prev);
    return (0);
}

int        main()
{
    get_time_laps();
    return (0);
}

the result is :

diff : 0 seconds and 0 microseconds
diff : 0 seconds and 47 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 2 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 1 microseconds
diff : 0 seconds and 0 microseconds
[...]
diff : 0 seconds and 1 microseconds

So I m wondering why the 2nd diff is so different from the others.. FYI I made the test several times, every times I get this pattern.


Solution

  • The reason this happens is quite interesting. Since gettimeofday would use a syscall that is called very often, linux uses a thing call vdso, which is a so that is mapped automatically in your program in order to access the things related to the time information without the need of a syscall (since syscalls are costly).

    The way this works is that when you call gettimeofday, your program will look for the symbol in vdso. and when it finds it, i will cache it in its memory for faster accesses. thats why the first call is slower. You can find a way better explanation here

    Oftentimes the C library will do detection with the first call and then cache the result for subsequent calls.

    And a nice way to benchmark the vdso vs the actual syscall here