【问题标题】:Linux clock_gettime(CLOCK_MONOTONIC) strange non-monotonic behaviorLinux clock_gettime(CLOCK_MONOTONIC) 奇怪的非单调行为
【发布时间】:2011-10-13 14:17:52
【问题描述】:

伙计们,在我的应用程序中,我使用clock_gettime(CLOCK_MONOTONIC) 来测量帧之间的增量时间(gamedev 中的一种典型方法),有时我会遇到clock_gettime(..) 的奇怪行为 - 返回值偶尔不是单调的(即上一时间大于当前时间)。

目前,如果发生这种悖论,我只需跳过当前帧并开始处理下一帧。

问题是这怎么可能呢?它是clock_gettime 的 Linux POSIX 实现中的错误吗?我使用的是 Ubuntu Server Edition 10.04(内核 2.6.32-24,x86_64),gcc-4.4.3。

【问题讨论】:

  • 您是否有机会在虚拟化环境中运行它?
  • 不,不涉及虚拟化

标签: linux gcc clock


【解决方案1】:

man clock_gettime 说:

CLOCK_MONOTONIC_RAW(自 Linux 2.6.28 起;特定于 Linux)

类似于 CLOCK_MONOTONIC,但提供对不受 NTP 调整影响的基于硬件的原始时间的访问。

由于CLOCK_MONOTONIC_RAW 不受NTP 调整,我猜CLOCK_MONOTONIC 可能。

我们在使用 2.6.18 内核和一些特定的 Itanium 处理器的 Redhat Enterprise 5.0 中遇到了类似的问题。我们无法在同一操作系统上使用其他处理器重现它。它已在 RHEL 5.3 中修复,内核稍新,并带有一些 Redhat 补丁。

【讨论】:

  • 感谢您的提示。给我的另一个教训 - 即使是最可靠的库,也永远不要绝对信任 :)
  • 我在内核时钟函数上工作了一段时间。它假定的工作方式是MONOTONIC 时钟永远不会倒退。这就是定义。
  • 在实践中,MONOTONIC 是作为 REALTIME 的偏移量实现的。任何时候调整实时时钟或系统休眠,都会调整此偏移量。在错误的情况下,偏移量可能计算错误,导致单调时钟的跳跃——甚至是向后跳跃。
  • OP 没有提到错误有多大,但这是我的经验:大多数硬件中的内置实时时钟只提供最接近秒的时间,而 Linux 内部保持最接近的时间微秒或纳秒。 Linux 试图在睡觉和醒来时解决这些问题,但逻辑相当复杂,我不明白。再加上由 NTP 调整、用户时间调整以及谁知道还有什么引起的 REALTIME 调整,你就有了混乱的秘诀。最重要的是,我并不感到惊讶 MOTONIC 有时会倒退。
  • CLOCK_MONOTONIC 不应该向后(或向前)跳跃;如果是这样,那是一个错误。它受到 NTP 守护程序的细微调整(看起来像百万分之 500),而 CLOCK_MONOTONIC_RAW 则不是。我的理解是“原始”单调时钟可能不是 100% 准确的,因此 NTP 守护程序可以加快或减慢一点点,以使其与实际时间流逝相匹配。如果你想每秒做 N 次事情,非原始时钟可能更准确。
【解决方案2】:

看起来像一个实例

commit 0696b711e4be45fa104c12329f617beb29c03f78
Author: Lin Ming <ming.m.lin@intel.com>
Date:   Tue Nov 17 13:49:50 2009 +0800

timekeeping: Fix clock_gettime vsyscall time warp

Since commit 0a544198 "timekeeping: Move NTP adjusted clock
multiplier to struct timekeeper" the clock multiplier of vsyscall is updated with
the unmodified clock multiplier of the clock source and not with the
NTP adjusted multiplier of the timekeeper.

This causes user space observerable time warps:
new CLOCK-warp maximum: 120 nsecs,  00000025c337c537 -> 00000025c337c4bf

请参阅here 获取补丁。这已包含在 2.6.32.19 中,但可能没有被 Debian 团队向后移植(?)。你应该检查一下。

【讨论】:

    【解决方案3】:

    试试CLOCK_MONOTONIC_RAW

    【讨论】:

      【解决方案4】:

      对我来说听起来确实是个错误。也许你应该在Ubuntu's bug tracker 报告它。

      【讨论】:

      • Bug 跟踪器很好,提交 bug 也很好(每个人都应该这样做),但它们不受欢迎,因为程序员现在想要修复。通常上游的错误要等到你完成项目的大部分编码后很久才会修复,而且你必须支持那些很久没有升级上游库的人。 :(
      【解决方案5】:

      这是一个 linux 错误。单调时钟中的任何调整都不能使它倒退。您使用的是非常旧的内核和非常旧的发行版。

      编辑:你确定你需要跳帧吗?如果再次调用clock_gettime,会发生什么?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        相关资源
        最近更新 更多