c - 在 Linux 中测量时间 - 时间 vs 时钟 vs getrusage vs clock

在计时功能中,time , clock getrusage , clock_gettime , gettimeofdaytimespec_get ,我想清楚地了解它们是如何实现的以及它们的返回值是什么,以便知道我必须在哪种情况下使用它们。

首先我们需要对返回 的函数进行分类挂钟值 与返回 的函数进行比较进程或线程值 . gettimeofday返回挂钟值,clock_gettime返回挂钟值 进程或线程值取决于 Clock传递给它的参数。 getrusageclock返回过程值。

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

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

还有其他功能吗?

最佳答案

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

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

  • 在开始列表之前,我想指出挂钟时间很少是正确的使用时间,而它会随着时区变化、夏令时变化或挂钟是否由 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 开始,它是用 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) 实现的在 Linux 中。
  • clock_gettime(CLOCK_MONOTONIC, ...) 提供纳秒分辨率,是单调的。我相信“秒”和“纳秒”是分开存储的,每个都在 32 位计数器中。因此,在几十年的正常运行后,任何回绕都会发生。这看起来是一个非常好的时钟,但不幸的是,它在 OS X 上尚不可用。POSIX 7 describes CLOCK_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 并实现它 as a system call .
  • mach_absolute_time() 是 OS X 上非常高分辨率 (ns) 计时的一个选项。在我的系统上,这确实提供了 ns 分辨率。原则上,这个时钟环绕,但是它使用 64 位无符号整数存储 ns,因此环绕在实践中不应该是一个问题。便携性值得怀疑。
  • I wrote a hybrid function基于 this snippet在 Linux 上编译时使用 clock_gettime,在 OS X 上编译时使用 Mach 计时器,以便在 Linux 和 OS X 上获得 ns 精度。

  • 除非另有说明,否则上述所有内容都存在于 Linux 和 OS X 中。上面的“我的系统”是运行 OS X 10.8.3 和来自 MacPorts 的 GCC 4.7.2 的 Apple。

    最后,除了上面的链接之外,这里还有一个我认为有用的引用列表:
  • 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


  • 更新 : 对于 OS X,clock_gettime已于 10.12 (Sierra) 实现。此外,基于 POSIX 和 BSD 的平台(如 OS X)共享 rusage.ru_utime结构域。

    关于c - 在 Linux 中测量时间 - 时间 vs 时钟 vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12392278/

    相关文章:

    python - 如何在 Python 中直接获取字典键作为变量(而不是通过从值中搜索)?

    python - 如何编写符合 PEP8 的超长字符串并防止 E501

    python - 在python中将一个列表插入另一个列表的语法是什么?

    python - 从 django 的查询集中获取第一个对象的最快方法?

    linux - 了解 Linux/proc/pid/maps 或/proc/self/maps

    mysql - 有没有办法只安装mysql客户端(Linux)?

    c - 写入 .txt 文件?

    python - 如何编写好的/正确的包 __init__.py 文件

    python - 如果在 Python 中为 None,是否有返回默认值的简写?

    c - 使用 gcc 命令行从 .c 文件构建 .so 文件