在定时函数time
、clock
、getrusage
、clock_gettime
、gettimeofday
和timespec_get
中,我想清楚地了解它们是如何实现的,以及它们的返回值是什么,以便知道在什么情况下必须使用它们。
首先,我们需要对返回挂钟值的函数进行分类,并与返回进程或线程值的函数进行比较。gettimeofday
返回挂钟值,clock_gettime
返回挂钟值或进程或线程值,具体取决于传递给它的Clock
参数。getrusage
和clock
返回进程值。
然后第二个问题是关于这些功能的实现以及它们的准确性。这些功能使用哪种硬件或软件机制。getrusage
似乎只使用内核标记(通常1ms长),因此不能比ms更精确。对吗?然后gettimeofday
函数似乎使用了最精确的底层硬件。因此,其精度通常为微秒(不能更多,因为API)在最近的硬件上。clock
怎么样,手册页谈到“近似”,它是什么意思?clock_gettime
怎么样,API是纳秒,这是否意味着如果底层硬件允许的话,它能够如此准确?单调性呢?
还有其他功能吗?
2条答案
按热度按时间at0kjp5o1#
问题是在C和C++中有几个不同的时间函数,其中一些在实现之间的行为不同。也有很多不完全的答案。编译一个时钟函数及其属性的列表将正确回答这个问题。首先让我们问一下我们正在寻找的相关属性是什么。看看你的帖子,我建议:
在开始列表之前,我想指出的是,墙上的时钟时间很少是正确的时间,而它会随着时区的变化而变化,夏令时的变化,或者如果墙上的时钟是由NTP同步的。如果你用时间来安排事件或基准测试性能,那么这些都不是好的。它只适用于顾名思义的墙上(或桌面)的时钟。
以下是我目前在Linux和OS X中发现的时钟:
time()
从操作系统返回挂钟时间,精度以秒为单位。clock()
似乎返回用户和系统时间的总和。它存在于C89及以后的版本中。曾经这应该是以周期为单位的CPU时间,但现代标准like POSIX要求CLOCKS_PER_SEC为1000000,给出了1 µs的最大可能精度。我的系统上的精度确实是1 µs。这个时钟在达到最高值后会绕回(这通常发生在~2^32次滴答之后,对于1 MHz时钟来说并不长).man clock
说,自glibc 2.18以来,它在Linux中使用clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)
实现。clock_gettime(CLOCK_MONOTONIC, ...)
提供纳秒分辨率,是单调的。我相信“秒”和“纳秒”是分开存储的,每个都在32位计数器中。因此,任何回绕都会在正常运行几十年后发生。这看起来像是一个非常好的时钟,但不幸的是,它还没有在OS X上可用。POSIX 7 describesCLOCK_MONOTONIC
as an optional extension。getrusage()
是我的最佳选择,它可以分别报告用户时间和系统时间,而且不会绕回,在我的系统上精度是1 µs,但我也在Linux系统(Red Hat 4.1.2-48 with GCC 4.1.2)上测试过,精度只有1 ms。gettimeofday()
返回挂钟时间(名义上)µs精度。在我的系统上,这个时钟似乎确实具有µs精度,但这并不能保证,因为"the resolution of the system clock is hardware dependent". POSIX. 1 -2008 says that.“应用程序应该使用clock_gettime()
函数,而不是过时的gettimeofday()
函数”,所以你应该远离它。Linux x86并将其实现为系统调用。mach_absolute_time()
是OS X上非常高分辨率(ns)计时的一个选项。在我的系统上,这确实给予ns分辨率。原则上这个时钟是环绕的,但是它使用64位无符号整数存储ns,所以环绕在实践中应该不是问题。可移植性是有问题的。上面的所有内容都存在于Linux和OS X中,除非另有说明。上面的“我的系统”是运行Mac Ports的OS X 10.8.3和GCC 4.7.2的Apple。
最后,除了上面的链接外,这里还有一个参考文献列表,我发现这些参考文献很有帮助:
更新:对于OS X,
clock_gettime
从10.12(Sierra)开始实现。此外,基于POSIX和BSD的平台(如OS X)共享rusage.ru_utime
结构域。fnvucqvd2#
C11
timespec_get
使用示例:https://stackoverflow.com/a/36095407/895245
返回的最大可能精度为纳秒,但实际精度由实现定义,可能更小。
它返回的是墙时间,而不是CPU使用率。
glibc 2.21在
sysdeps/posix/timespec_get.c
下实现了它,它直接转发到:clock_gettime
和CLOCK_REALTIME
是POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html,而man clock_gettime
表示,如果在程序运行时更改某些系统时间设置,则此度量可能具有不连续性。C++11 chrono
既然我们在这里,让我们也涵盖它们:http://en.cppreference.com/w/cpp/chrono
GCC 5.3.0(C++ stdlib在GCC源代码中):
high_resolution_clock
是system_clock
的别名system_clock
转发到以下可用的第一个:clock_gettime(CLOCK_REALTIME, ...)
gettimeofday
time
steady_clock
转发到以下可用的第一个:clock_gettime(CLOCK_MONOTONIC, ...)
system_clock
标签:Difference between std::system_clock and std::steady_clock?
CLOCK_REALTIME
与CLOCK_MONOTONIC
:Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?