System.nanoTime()完全没用吗? [英] Is System.nanoTime() completely useless?

查看:202
本文介绍了System.nanoTime()完全没用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如博客文章 谨防Java中的System.nanoTime()所述 ,在x86系统上,Java的System.nanoTime()使用 CPU返回时间值特定的柜台。现在考虑我用来测量通话时间的以下情况:

As documented in the blog post Beware of System.nanoTime() in Java, on x86 systems, Java's System.nanoTime() returns the time value using a CPU specific counter. Now consider the following case I use to measure time of a call:

long time1= System.nanoTime();
foo();
long time2 = System.nanoTime();
long timeSpent = time2-time1;

现在在多核系统中,可能是在测量time1之后,线程被安排到一个不同的处理器,其计数器小于先前CPU的计数器。因此,我们可以在time2中获得一个值 less 而不是time1。因此我们在timeSpent中得到一个负值。

Now in a multi-core system, it could be that after measuring time1, the thread is scheduled to a different processor whose counter is less than that of the previous CPU. Thus we could get a value in time2 which is less than time1. Thus we would get a negative value in timeSpent.

考虑到这种情况,现在不是System.nanotime几乎没用了吗?

Considering this case, isn't it that System.nanotime is pretty much useless for now?

我知道改变系统时间不会影响纳米时间。这不是我上面描述的问题。问题是每个CPU都会在打开后保留不同的计数器。与第一个CPU相比,第二个CPU上的计数器可以更低。由于在获取time1后,操作系统可以将线程调度到第二个CPU,因此timeSpent的值可能不正确甚至是负数。

I know that changing the system time doesn't affect nanotime. That is not the problem I describe above. The problem is that each CPU will keep a different counter since it was turned on. This counter can be lower on the second CPU compared to the first CPU. Since the thread can be scheduled by the OS to the second CPU after getting time1, the value of timeSpent may be incorrect and even negative.

推荐答案

该帖子错误, nanoTime 是安全的。该帖子上有评论链接到 David Holmes的博客文章,这是一个实时和Sun的并发人员。它说:

That post is wrong, and nanoTime is safe. There's a comment on the post which links to a blog post by David Holmes, a realtime and concurrency guy at Sun. It says:


使用QueryPerformanceCounter / QueryPerformanceFrequency API实现System.nanoTime()[...] QPC使用的默认机制是由硬件抽象层(HAL)确定[...]此默认值不仅会在硬件之间更改,还会在OS版本之间更改。例如,Windows XP Service Pack 2改变了使用电源管理计时器(PMTimer)而不是处理器时间戳计数器(TSC)的原因,因为TSC的问题未在SMP系统中的不同处理器上同步,并且由于其频率可以根据电源管理设置变化(因此它与经过时间的关系)。

System.nanoTime() is implemented using the QueryPerformanceCounter/QueryPerformanceFrequency API [...] The default mechanism used by QPC is determined by the Hardware Abstraction layer(HAL) [...] This default changes not only across hardware but also across OS versions. For example Windows XP Service Pack 2 changed things to use the power management timer (PMTimer) rather than the processor timestamp-counter (TSC) due to problems with the TSC not being synchronized on different processors in SMP systems, and due the fact its frequency can vary (and hence its relationship to elapsed time) based on power-management settings.

所以,在Windows上,这个直到WinXP SP2才出现问题,但现在还没有。

So, on Windows, this was a problem up until WinXP SP2, but it isn't now.

我找不到第二部分(或更多部分)谈论其他问题平台,但该文章确实包含Linux遇到的注释并以相同的方式解决了同样的问题,链接指向 clock_gettime(CLOCK_REALTIME)的常见问题解答,其中包含:

I can't find a part II (or more) that talks about other platforms, but that article does include a remark that Linux has encountered and solved the same problem in the same way, with a link to the FAQ for clock_gettime(CLOCK_REALTIME), which says:



  1. 是clock_gettime(CLOCK_REALTIME )所有处理器/核心是否一致? (拱形是否重要?例如ppc,arm,x86,amd64,sparc)。

应该或它被认为是错误的。

It should or it's considered buggy.

然而,在x86 / x86_64上,可能会看到未同步或变量的频率TSC导致时间不一致。 2.4内核确实没有针对此的保护,早期的2.6内核也没有做得太好。从2.6.18开始,用于检测的逻辑更好,我们通常会回到安全的时钟源。

However, on x86/x86_64, it is possible to see unsynced or variable freq TSCs cause time inconsistencies. 2.4 kernels really had no protection against this, and early 2.6 kernels didn't do too well here either. As of 2.6.18 and up the logic for detecting this is better and we'll usually fall back to a safe clocksource.

ppc总是有一个同步的时基,所以不应该是一个问题。

ppc always has a synced timebase, so that shouldn't be an issue.

因此,如果Holmes的链接可以理解为暗示 nanoTime 调用 clock_gettime(CLOCK_REALTIME),然后从x86上的内核2.6.18开始就是安全的,并且总是在PowerPC上(因为IBM和摩托罗拉不同于英特尔) ,实际上知道如何设计微处理器。)

So, if Holmes's link can be read as implying that nanoTime calls clock_gettime(CLOCK_REALTIME), then it's safe-ish as of kernel 2.6.18 on x86, and always on PowerPC (because IBM and Motorola, unlike Intel, actually know how to design microprocessors).

遗憾的是,没有提到SPARC或Solaris。当然,我们不知道IBM JVM的功能。但现代Windows和Linux上的Sun JVM正确。

There's no mention of SPARC or Solaris, sadly. And of course, we have no idea what IBM JVMs do. But Sun JVMs on modern Windows and Linux get this right.

编辑:这个答案是基于它引用的来源。但我仍然担心它可能实际上是完全错误的。一些更新的信息将非常有价值。我刚看到一个指向的链接关于Linux时钟的四年新文章可能很有用。

This answer is based on the sources it cites. But i still worry that it might actually be completely wrong. Some more up-to-date information would be really valuable. I just came across to a link to a four year newer article about Linux's clocks which could be useful.

这篇关于System.nanoTime()完全没用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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