首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >gettimeofday函数的精度是多少?

gettimeofday函数的精度是多少?
EN

Stack Overflow用户
提问于 2021-09-08 08:40:52
回答 2查看 674关注 0票数 4

我正在读奥斯特的single.dvi一章。在家庭作业部分,它说:

你必须考虑的一件事是你的计时器的精确性和准确性。您可以使用的一个典型计时器是gettimeofday();读取手册页以获得详细信息。您将看到的是,自1970年以来,gettimeofday()返回的时间以微秒为单位;然而,这并不意味着定时器精确到微秒。度量对gettimeofday()的背对背调用,以了解定时器的精确程度;这将告诉您,为了获得良好的测量结果,您必须运行多少次空系统调用测试。如果gettimeofday()不够精确,您可以考虑使用x86机器上可用的rdtsc指令。

我编写了一些代码来测试调用gettimeofday()函数的成本,如下所示:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <sys/time.h>

#define MAX_TIMES 100000

void m_gettimeofday() {
    struct timeval current_time[MAX_TIMES];
    int i;
    for (i = 0; i < MAX_TIMES; ++i) {
        gettimeofday(&current_time[i], NULL);
    }
    printf("seconds: %ld\nmicro_seconds: %ld\n", current_time[0].tv_sec, current_time[0].tv_usec);
    printf("seconds: %ld\nmicro_seconds: %ld\n", current_time[MAX_TIMES - 1].tv_sec, current_time[MAX_TIMES - 1].tv_usec);
    printf("the average time of a gettimeofday function call is: %ld us\n", (current_time[MAX_TIMES - 1].tv_usec - current_time[0].tv_usec) / MAX_TIMES);
}

int main(int argc, char *argv[]) {
    m_gettimeofday();
    return 0;
}

但是,输出总是0微秒。gettimeofday()函数的精度似乎正好是1微秒。我的测试代码怎么了?还是我误解了作者的意思?谢谢你的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-08 08:48:24

在连续调用gettimeofday之间传递的平均微秒通常是小于一个--在我的机器上,这个值在0.05到0.15之间。

现代CPU通常以GHz的速度运行--即每秒数十亿条指令,因此两个连续的指令应该是纳秒级,而不是微秒级(显然,对像gettimeofday这样的函数的两个调用比两个简单的操作码更复杂,但它仍然应该是几十纳秒级的,而不是更多的)。

但是您正在执行ints的一个除法--除以(current_time[MAX_TIMES - 1].tv_usec - current_time[0].tv_usec)除以MAX_TIMES --在C中,它也将返回一个int,在本例中为0。

要获得真正的度量,用(double)MAX_TIMES除以(并将结果打印成双倍):

代码语言:javascript
运行
复制
printf("the average time of a gettimeofday function call is: %f us\n", (current_time[MAX_TIMES - 1].tv_usec - current_time[0].tv_usec) / (double)MAX_TIMES);

在Linux系统上,gettimeofday之所以如此快速(您可能会认为它是一个更复杂的函数,调用内核并产生syscall的开销)的原因在于,它有一个名为vdso的特殊特性,它允许内核向用户空间提供信息,而不需要遍历内核。

票数 5
EN

Stack Overflow用户

发布于 2021-09-10 11:11:11

gettimeofday(2)被宣布为过时的clock_gettime(2),它的分辨率比旧的要好(它使用纳秒分辨率)

分裂是另一个(不同的)问题,因为它取决于硬件如何允许您获得时间戳以及操作系统如何实现它。

在基于linux/intel的系统中,通常有很好的硬件可用,并且它是由linux很好地实现的,所以在处理时间戳时通常可以获得真正的纳秒精度。但是,不要试图在一台没有PPS的机器上获得这种精度,因为它的石英振荡器很差。您没有指定您需要获得什么样的时间戳,但是如果您需要获得绝对时间戳,并将其与官方时间进行比较,请不要期望它们比几百毫秒更近(基于一个带有普通石英振荡器的NTP同步机器)。

无论如何,要获得您计划的电话的平均时间,您有两个问题:

  • 您需要调用MAX_TIMES + 1乘以您的gettimeofday(2)系统调用,因为您正在测量两个时间戳之间的时间(因此您计算了调用系统调用之间的时间,它能够获得时间戳,而从时间戳到返回值的时间被传递到调用例程--但顺序相反)最好的方法是在开始时取一个时间戳t0,在t1中取最后的MAX_TIMES时间戳。只有这样,您才能确定t0t1之间的时间,并将其划分为MAX_TIMES。为此,从t0.tv_usec中减去t1.tv_usec,如果结果小于零,则向其添加1000000,并增加t1.tv_sec - t0.tv_sec中的差值。tv_sec将有秒数的差异,而tv_usec将有超过微秒的秒数。
  • 这假设系统调用开销没有变化,而这不是真的。有时,系统调用比其他调用花费更多的时间,您感兴趣的值不是它们的平均值,而是它可以达到的最小值。但你可以符合平均,因为你不会进入到usec决议。

我建议您使用clock_gettime(2)系统调用,因为它具有纳秒分辨率。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69099750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档