在 Linux 中测量时间 - 时间 vs 时钟 vs getrusage vs clock_gettime vs gettimeofday vs timespec_get? [英] Measure time in Linux - time vs clock vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?

查看:24
本文介绍了在 Linux 中测量时间 - 时间 vs 时钟 vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

计时函数中,timeclock getrusageclock_gettimegettimeofdaytimespec_get,我想清楚地了解它们是如何实现的以及它们的返回值是什么,以便知道我必须在哪种情况下使用它们.

Among the timing functions, time, clock getrusage, clock_gettime, gettimeofday and timespec_get, I want to understand clearly how they are implemented and what are their return values in order to know in which situation I have to use them.

首先,我们需要将返回挂钟值的函数与返回进程或线程值的函数进行分类.gettimeofday 返回挂钟值,clock_gettime 根据 Clock 返回挂钟值 进程或线程值传递给它的参数.getrusageclock 返回进程值.

First we need to classify functions returning wall-clock values compare to functions returning process or threads values. gettimeofday returns wall-clock value, clock_gettime returns wall-clock value or process or threads values depending on the Clock parameter passed to it. getrusage and clock return process values.

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

Then the second question regards the implementation of these functions and as a consequence, their accuracy. Which hardware or software mechanism does these functions use.

似乎 getrusage 仅使用内核滴答(通常为 1 毫秒长),因此不会比 ms 更准确.这样对吗?然后 getimeofday 函数似乎使用了最准确的可用底层硬件.因此,在最近的硬件上,它的精度通常是微秒(由于 API 而不能更多).clock 怎么样,手册页讲了近似",是什么意思?clock_gettime 怎么样,API 是纳秒级的,这是否意味着如果底层硬件允许它能够如此准确?单调性怎么样?

It seems that getrusage uses only the kernel tick (usually 1ms long) and as a consequence can't be more accurate than the ms. Is it right? Then the getimeofday function seems to use the most accurate underlying hardware available. As a consequence its accuracy is usually the microsecond (can't be more because of the API) on recent hardware. What about clock, the man page speak about "approximation", what does it mean? What about clock_gettime, the API is in nanosecond, does it means that it's able to be so accurate if underlying hardware allows it? What about monotonicity?

还有其他功能吗?

推荐答案

问题是 C 和 C++ 中有几种不同的时间函数可用,其中一些在实现之间的行为有所不同.也有很多半信半疑的答案.编译时钟函数列表及其属性将正确回答问题.首先,让我们问问我们正在寻找的相关属性是什么.看了你的帖子,我建议:

The problem is that there are several different time functions available in C and C++, and some of them vary in behavior between implementations. There are also a lot of half-answers floating around. Compiling a list of clock functions together with their properties would answer the question properly. For starts let's ask what the relevant properties are that we're looking for. Looking at your post, I suggest:

  • 时钟测量的是什么时间?(真实的、用户的、系统的,还是希望不是挂钟?)
  • 时钟的精度是多少?(s、ms、µs 还是更快?)
  • 时钟大约经过多少时间?或者有什么机制可以避免这种情况?
  • 时钟是单调的,还是会随着系统时间的变化(通过 NTP、时区、夏令时、用户等)而变化?
  • 上述内容在不同实现之间有何不同?
  • 具体功能是否过时、不标准等?

在开始列表之前,我想指出挂钟时间很少是正确的使用时间,而它会随着时区的变化、夏令时的变化或挂钟与 NTP 同步而变化.如果您使用时间来安排事件或对性能进行基准测试,那么这些事情都没有好处.它只是因为名字所说的那样好,墙上(或桌面)上的时钟.

Before starting the list, I'd like to point out that wall-clock time is rarely the right time to use, whereas it changes with time zone changes, daylight savings time changes, or if the wall clock is synchronized by NTP. None of these things are good if you're using the time to schedule events or to benchmark performance. It's only really good for what the name says, a clock on the wall (or desktop).

这是我目前在 Linux 和 OS X 中找到的时钟:

Here's what I've found so far for clocks in Linux and OS X:

  • time() 返回挂钟时间来自操作系统,精确到秒.
  • clock() 似乎返回了用户时间和系统时间.它存在于 C89 及更高版本中.曾经这应该是 CPU 周期时间,但现代标准 像 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 CLOCK_MONOTONIC 描述为可选扩展.
  • getrusage() 结果证明是最好的我的情况的选择.它分别报告用户和系统时间并且不回绕.我的系统上的精度是 1 µs,但我也在 Linux 系统(Red Hat 4.1.2-48 with GCC 4.1.2)上测试过,精度只有 1 ms.
  • gettimeofday() 返回挂钟时间具有(名义上)μs 精度.在我的系统上,这个时钟似乎有 µs 精度,但这不能保证,因为 "系统时钟取决于硬件".POSIX.1-2008 .应用程序应该使用 clock_gettime() 函数而不是过时的 gettimeofday() 函数",所以你应该远离它.Linux x86 并将其实现 作为系统调用.
  • mach_absolute_time() 是 OS X 上非常高分辨率 (ns) 计时的一个选项.在我的系统上,这确实提供了 ns 分辨率.原则上这个时钟是环绕的,但是它使用 64 位无符号整数存储 ns,所以环绕在实践中不应该是一个问题.便携性值得怀疑.
  • 我写了一个混合函数基于此代码段,在Linux或Mach上编译时使用clock_gettime在 OS X 上编译时的计时器,以便在 Linux 和 OS X 上获得 ns 精度.
  • time() returns the wall-clock time from the OS, with precision in seconds.
  • clock() seems to return the sum of user and system time. It is present in C89 and later. At one time this was supposed to be the CPU time in cycles, but modern standards like POSIX require CLOCKS_PER_SEC to be 1000000, giving a maximum possible precision of 1 µs. The precision on my system is indeed 1 µs. This clock wraps around once it tops out (this typically happens after ~2^32 ticks, which is not very long for a 1 MHz clock). man clock says that since glibc 2.18 it is implemented with clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) in Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) provides nanosecond resolution, is monotonic. I believe the 'seconds' and 'nanoseconds' are stored separately, each in 32-bit counters. Thus, any wrap-around would occur after many dozen years of uptime. This looks like a very good clock, but unfortunately it isn't yet available on OS X. POSIX 7 describes CLOCK_MONOTONIC as an optional extension.
  • getrusage() turned out to be the best choice for my situation. It reports the user and system times separately and does not wrap around. The precision on my system is 1 µs, but I also tested it on a Linux system (Red Hat 4.1.2-48 with GCC 4.1.2) and there the precision was only 1 ms.
  • gettimeofday() returns the wall-clock time with (nominally) µs precision. On my system this clock does seem to have µs precision, but this is not guaranteed, because "the resolution of the system clock is hardware dependent". POSIX.1-2008 says that. "Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function", so you should stay away from it. Linux x86 and implements it as a system call.
  • mach_absolute_time() is an option for very high resolution (ns) timing on OS X. On my system, this does indeed give ns resolution. In principle this clock wraps around, however it is storing ns using a 64-bit unsigned integer, so the wrapping around shouldn't be an issue in practice. Portability is questionable.
  • I wrote a hybrid function based on this snippet that uses clock_gettime when compiled on Linux, or a Mach timer when compiled on OS X, in order to get ns precision on both Linux and OS X.

以上所有内容都存在于 Linux 和 OS X 中,除非另有说明.上面的我的系统"是运行 OS X 10.8.3 和来自 MacPorts 的 GCC 4.7.2 的 Apple.

All of the above exist in both Linux and OS X except where otherwise specified. "My system" in the above is an Apple running OS X 10.8.3 with GCC 4.7.2 from MacPorts.

最后,除了上面的链接之外,还有一个我认为有用的参考列表:

Finally, here is a list of references that I found helpful in addition to the links above:

更新:对于 OS X,clock_gettime 已从 10.12 (Sierra) 开始实施.此外,基于 POSIX 和 BSD 的平台(如 OS X)共享 rusage.ru_utime 结构字段.

Update: for OS X, clock_gettime has been implemented as of 10.12 (Sierra). Also, both POSIX and BSD based platforms (like OS X) share the rusage.ru_utime struct field.

这篇关于在 Linux 中测量时间 - 时间 vs 时钟 vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆