1

这个功能对我来说很新,所以我只是写了一个小程序来熟悉它。这是我的程序(只是在几次 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);
}

结果是:

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

所以我想知道为什么第二个差异与其他差异如此不同.. 仅供参考,我做了几次测试,每次我得到这个模式。

4

1 回答 1

2

发生这种情况的原因很有趣。由于 gettimeofday 会使用一个经常被调用的系统调用,Linux 使用了一个叫 vdso 的东西,它是一个在你的程序中自动映射的 so,以便在不需要系统调用的情况下访问与时间信息相关的东西(因为系统调用是昂贵的)。

其工作方式是,当您调用 gettimeofday 时,您的程序将在 vdso 中查找符号。当它找到它时,我会将它缓存在它的内存中以便更快地访问。这就是为什么第一次通话较慢的原因。你可以在这里找到更好的解释

C 库通常会在第一次调用时进行检测,然后缓存结果以供后续调用。

还有一个很好的方法来对 vdso 和实际的系统调用进行基准测试

于 2021-06-08T10:28:14.410 回答