【问题标题】:What's the worst resolution I can reasonably expect from System.nanoTime?我可以合理地从 System.nanoTime 获得的最差分辨率是多少?
【发布时间】:2017-10-11 21:52:50
【问题描述】:

我正在编写的软件需要微秒级或更高分辨率的时间戳。

我打算将System.currentTimeMillisSystem.nanoTime 结合使用,有点像这样,虽然这只是一个粗略的代码草图:

private static final long absoluteTime = (System.currentTimeMillis() * 1000 * 1000);
private static final long relativeTime = System.nanoTime();

public long getTime()
{
    final long delta = System.nanoTime() - relativeTime;
    if (delta < 0) throw new IllegalStateException("time delta is negative");
    return absoluteTime  + delta;
}

nanoTime 的文档说:

此方法提供纳秒级精度,但不一定 纳秒分辨率(即值更改的频率) - 否 除了决议至少与 currentTimeMillis()的那个。

所以它没有给我们提供比毫秒更好的分辨率保证。

nanoTime(可以预见的是本机方法)的引擎盖下再深入一点:

  • Windows 使用QueryPerformanceCounter API,它承诺 小于 1 微秒的分辨率非常棒。

  • Linux 使用带有标志的clock_gettime 来确保该值是 单调但不承诺分辨率。

  • Solaris 与 Linux 类似

  • 消息来源没有提到 OSX 或基于 Unix 的操作系统如何处理这个问题。

(source)

我已经看到了一些模糊的暗示,即它“通常”具有微秒级分辨率,例如 this answer 在另一个问题上:

在大多数系统上,三个最低有效数字始终是 零。这实际上给出了微秒精度,但在 固定精度为一纳秒。

但没有来源,而且“通常”这个词非常主观。

问题:在什么情况下nanoTime会返回一个分辨率低于微秒的值?例如,可能主要操作系统版本不支持它,或者需要可能不存在的特定硬件功能。如果可以,请尽量提供来源。


我正在使用 Java 1.6,但如果对这个问题有实质性的好处,我可以升级的可能性很小。

【问题讨论】:

  • 我很好奇你的用例是什么。显然,您不能期望时钟在设备之间如此紧密地同步。如果您从硬件录制某些内容,那么您将受到中断率的限制。
  • @user695022 金融立法规定,我们的时间戳必须是用于审计目的和其他东西的粒度。它们目前以毫秒为单位。
  • 对负数检查要小心,它看起来很正常,但可能存在时钟不平衡导致负数。示例见stackoverflow.com/questions/7866206/…
  • 您已经找到了它委托给哪些特定于平台的方法。您必须调查这些特定于平台的方法的行为。 linux 的clock_gettime 行为因硬件提供的不同而有很大差异。最终,由于平台和硬件特定的行为,规范被故意留下模糊不清。

标签: java linux windows time


【解决方案1】:

问题:nanoTime 在什么情况下会返回一个分辨率低于微秒的值?这可能会影响哪些比较常用的操作系统、硬件、JVM 等?如果可以的话,请尽量提供来源。

要求详尽列出违反该约束的所有可能情况似乎有点过分,没有人知道您的软件将在哪些环境下运行。但要证明它可以发生,请参阅blog post by aleksey shipilev,他描述了一个案例,由于争用,纳米时间在 Windows 机器上变得比微秒更不准确(就其自身的延迟而言)。

另一种情况是在虚拟机下运行的软件以非常粗略的方式模拟硬件时钟。

由于特定于平台和硬件的行为,规范故意含糊不清。

一旦您确认您使用的硬件和操作系统确实提供了您需要的功能并且虚拟机通过了必要的功能,您就可以“合理地期望”微秒级精度。

【讨论】:

  • 提到虚拟机是个好点。我不是在详尽的列表之后,也许提到一些可能会限制操作系统提供这种分辨率的能力的硬件功能会很好。
  • 如果我们将自己限制在 x86 和 linux 上,那么您基本上要确保 java 以最终使用 RDTSC 指令的方式调用 clock_gettime,您需要确保在多个级别(java ,操作系统,VM,处理器支持):stackoverflow.com/a/33718924/1362755
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
相关资源
最近更新 更多