2012-09-12 290 views
114

其中计时功能,timeclockgetrusageclock_gettimegettimeofdaytimespec_get,我想清楚地了解它们是如何实现的,为了知道在什么情况下我必须使用他们什么是他们的返回值。在Linux中测量时间 - 时间vs时钟vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?

首先,我们需要进行分类的功能恢复挂钟值比较返回处理功能或线程值gettimeofday返回挂钟值,clock_gettime返回挂钟值进程或线程值,具体取决于传递给它的参数Clockgetrusageclock返回过程值。

然后第二个问题关于这些功能的实现,因此,它们的准确性。这些功能使用哪种硬件或软件机制。

看来getrusage只使用内核tick(通常为1ms长),因此不能比ms更准确。这样对吗? 然后getimeofday函数似乎使用了最准确的底层硬件。因此,它的准确性通常是在最近的硬件上的微秒(不能因为API)。 关于clock,手册页讲的是“逼近”,这是什么意思? clock_gettime怎么样,API是纳秒,这是否意味着它可以如此精确,如果底层硬件允许它?单调性怎么样?

还有其他的功能吗?

回答

150

问题是在C和C++中有几种不同的时间函数可用,其中一些在实现之间的行为上有所不同。还有很多半答案浮动。编译时钟函数列表及其属性将正确回答问题。对于开始,让我们问一下我们正在寻找的相关属性。看看你的帖子,我建议:

  • 什么时候测量的时钟? (真实的,用户的,系统的,还是希望不是挂钟?)
  • 时钟的精度是多少? (s,ms,μs还是更快?)
  • 时钟回绕了多少时间?还是有一些机制可以避免这种情况?
  • 时钟是单调的,还是会随着系统时间的变化而改变(通过NTP,时区,夏令时,用户等)?
  • 上述内容在不同实现之间如何变化?
  • 特定功能是否过时,非标准等?

在开始列表之前,我想指出挂钟时间很少是正确的使用时间,而它随时区更改,夏时制时间更改或壁挂时钟更改由NTP同步。如果您使用时间安排活动或基准测试,这些都不是很好。这只是真正的好名字,墙上的时钟(或桌面)。

这里是我到目前为止已发现在Linux和OS X时钟:

  • time()从OS返回挂钟时间,精确的秒。
  • clock()似乎返回用户和系统时间的总和。它出现在C89及更高版本中。有一次,这应该是CPU周期的时间,但现代标准like POSIX要求CLOCKS_PER_SEC为1000000,最大可能的精度为1微秒。我的系统精度确实是1μs。这个时钟一旦回到顶部就会回绕(这通常发生在〜2^32个滴答声之后,对于1MHz时钟来说这不是很长)。 man clock表示,自glibc 2.18以来,它在Linux中与clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)一起实现。
  • clock_gettime(CLOCK_MONOTONIC, ...)提供纳秒分辨率,是单调的。我相信'秒'和'纳秒'分别存储在32位计数器中。因此,在正常运行数十年之后,任何绕回都会发生。这看起来像一个非常好的时钟,但不幸的是它还不能在OS X上使用。POSIX 7 describes CLOCK_MONOTONIC as an optional extension
  • getrusage()原来是我的情况的最佳选择。它分别报告用户和系统时间,不会环绕。我的系统精度为1微秒,但我也在Linux系统上进行了测试(Red Hat 4.1.2-48和GCC 4.1.2),精度仅为1毫秒。
  • gettimeofday()返回(标称)μs精度的挂钟时间。在我的系统上,这个时钟似乎具有μs精度,但这并不能保证,因为"the resolution of the system clock is hardware dependent"。 POSIX.1-2008 says that。 “应用程序应该使用clock_gettime()函数而不是过时的gettimeofday()函数”,因此您应该远离它。 Linux x86并实现它as a system call
  • mach_absolute_time()是OS X上的高分辨率(ns)定时选项。在我的系统上,这确实可以提供ns分辨率。原则上这个时钟环绕,但是它使用一个64位的无符号整数来存储ns,所以实际上这个环绕不应该是一个问题。可移植性值得怀疑。
  • I wrote a hybrid function基于this snippet使用clock_gettime在Linux上进行编译时,编译或OS X上的时候,为了获得在Linux纳秒的精度和OS X.马赫计时器

在上述所有的存在Linux和OS X都另有规定。上面的“我的系统”是一个运行OS X 10.8.3的Apple,MacPorts使用GCC 4.7.2。

最后,这里是我除了发现有助于上面的链接引用的列表:


更新:对于OS X,clock_gettime自10.12(Sierra)起实施。另外,基于POSIX和BSD的平台(如OS X)共享rusage.ru_utime结构体字段。在

+1

你现在有18个代表处点;-) –

+0

的Mac OS X没有'clock_gettime',因此,使用的[ 'gettimeofday()'](http://www.songho.ca/misc/timer/timer.html)比'clock_gettime()'更具多功能性'' – bobobobo

+0

@bobobobo我同意OS X没有clock_gettime() ),但gettimeofday()不幸地测量了挂钟时间。我更新了我的帖子以提供此信息。如果ms精度足够,那么我推荐使用getrusage()作为定时器的最佳时钟。 –

12

C11 timespec_get

用例:https://stackoverflow.com/a/36095407/895245

最大可能的精确度返回是纳秒,但实际精度为实现定义并且可能是较小的。

它返回挂墙时间,而不是CPU使用率。

的glibc 2.21 sysdeps/posix/timespec_get.c下实现它,它直接转发至:

clock_gettime (CLOCK_REALTIME, ts) < 0) 

clock_gettimeCLOCK_REALTIME是POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html,并且man clock_gettime说,这一措施可能具有不连续性,如果你改变一些系统时间,而你的程序运行设置。

C++ 11时辰

因为我们在这,我们要介绍他们还有:http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0(C++ stdlib的是GCC源里面):

  • high_resolution_clocksystem_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 VS CLOCK_MONOTONICDifference between CLOCK_REALTIME and CLOCK_MONOTONIC?

+1

谢谢你的补充。 –