在 Linux 中测量时间 - 时间 vs 时钟 vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12392278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Measure time in Linux - time vs clock vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?
提问by Manuel Selva
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.
其中计时功能,time
,clock
getrusage
,clock_gettime
,gettimeofday
和timespec_get
,我想清楚地了解它们是如何实现的,为了知道在什么情况下我必须使用他们什么是他们的返回值。
First we need to classify functions returning wall-clock valuescompare to functions returning process or threads values. gettimeofday
returns wall-clock value, clock_gettime
returns wall-clock value orprocess or threads values depending on the Clock
parameter passed to it. getrusage
and clock
return process values.
首先,我们需要将返回挂钟值的函数与返回进程或线程值的函数进行分类。gettimeofday
返回挂钟值,根据传递给它的参数clock_gettime
返回挂钟值或进程或线程值Clock
。getrusage
并clock
返回过程值。
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.
然后第二个问题是关于这些功能的实现,因此,它们的准确性。这些功能使用哪种硬件或软件机制。
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?
似乎getrusage
只使用内核滴答(通常为 1 毫秒长),因此不能比 ms 更准确。这样对吗?然后该getimeofday
函数似乎使用了可用的最准确的底层硬件。因此,在最近的硬件上,它的精度通常是微秒(由于 API 的缘故,不能更多)。怎么样clock
,手册页谈到“近似”,这是什么意思?怎么样clock_gettime
,API 以纳秒为单位,这是否意味着如果底层硬件允许它能够如此准确?单调性怎么样?
Are there any other functions?
还有其他功能吗?
采纳答案by Douglas B. Staple
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:
问题是在 C 和 C++ 中有几种不同的时间函数可用,其中一些在实现之间的行为有所不同。也有很多半信半疑的答案。编译时钟函数列表及其属性将正确回答问题。首先,让我们问一下我们正在寻找的相关属性是什么。看了你的帖子,我建议:
- What time is measured by the clock? (real, user, system, or, hopefully not, wall-clock?)
- What is the precision of the clock? (s, ms, μs, or faster?)
- After how much time does the clock wrap around? Or is there some mechanism to avoid this?
- Is the clock monotonic, or will it change with changes in the system time (via NTP, time zone, daylight savings time, by the user, etc.)?
- How do the above vary between implementations?
- Is the specific function obsolete, non standard, etc.?
- 时钟测量的是什么时间?(真实的,用户的,系统的,或者,希望不是,挂钟?)
- 时钟的精度是多少?(s、ms、μs 或更快?)
- 时钟回绕多少时间?或者有什么机制可以避免这种情况?
- 时钟是单调的,还是会随着系统时间的变化(通过 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).
在开始列出列表之前,我想指出挂钟时间很少是正确的使用时间,而它会随着时区的变化、夏令时的变化或挂钟是否由 NTP 同步而变化。如果您使用时间来安排事件或对性能进行基准测试,那么这些事情都没有好处。它只对名字所说的有用,墙上(或桌面)上的时钟。
Here's what I've found so far for clocks in Linux and OS X:
以下是我目前在 Linux 和 OS X 中找到的时钟:
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 POSIXrequire 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 withclock_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 describesCLOCK_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 theclock_gettime()
function instead of the obsolescentgettimeofday()
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 functionbased on this snippetthat 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.
time()
从操作系统返回挂钟时间,精度以秒为单位。clock()
似乎返回用户和系统时间的总和。它存在于 C89 及更高版本中。曾几何时,这应该是 CPU 周期时间,但现代标准(如 POSIX)要求 CLOCKS_PER_SEC 为 1000000,最大可能精度为 1 μs。我的系统的精度确实是 1 μs。这个时钟一旦达到顶峰就会回绕(这通常发生在 ~2^32 个滴答之后,这对于 1 MHz 时钟来说不是很长)。man clock
说从 glibc 2.18 开始,它是clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)
在 Linux 中实现的。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 上编译时使用 clock_gettime,或者在 OS X 上编译时使用 Mach 计时器,以便在 Linux 和 OS X 上获得 ns 精度。
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.
除非另有说明,否则上述所有内容都存在于 Linux 和 OS X 中。上面的“我的系统”是运行 OS X 10.8.3 和来自 MacPorts 的 GCC 4.7.2 的 Apple。
Finally, here is a list of references that I found helpful in addition to the links above:
最后,除了上面的链接之外,这里还有一个我认为有用的参考列表:
- http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
- How to measure the ACTUAL execution time of a C program under Linux?
- http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
- http://www.unix.com/hp-ux/38937-getrusage.html
- http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
- Linux下如何测量C程序的ACTUAL执行时间?
- http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
- http://www.unix.com/hp-ux/38937-getrusage.html
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.
更新:对于 OS X,clock_gettime
已从 10.12 (Sierra) 开始实施。此外,基于 POSIX 和 BSD 的平台(如 OS X)共享rusage.ru_utime
struct 字段。