根据CPU时钟测量时间?

时间:2012-04-19 19:09:40

标签: java performance

我已经阅读了一些低延迟技术论文,他们通过CPU测量时序,因为它更准确。

通常在Java中我会使用:

System.nanoTime()

并且在C ++中我相信我曾经使用过一种性能计数器方法,我在网上发现它可以精确到纳秒。它使用了一个LARGE_INTEGER,分配给你想要测量的精度,然后通过引用传递给QueryPerformanceCounter()并返回一个除以频率的答案。

是否存在根据CPU测量时间的Java等效代码,或者是否必须使用某种PInvoke?

编辑:

https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCYQFjAA&url=http%3A%2F%2Fdisruptor.googlecode.com%2Ffiles%2FDisruptor-1.0.pdf&ei=ImmQT5WQMOaW0QWW2sTwAQ&usg=AFQjCNEeGmYXzJa8huMdRGN2p4n8YH-jfg

  

要达到这种精度水平,必须使用时间戳   来自CPU的计数器。我们选择了具有不变TSC的CPU,因为   较旧的处理器由于省电而受到频率变化的影响   和睡眠状态。

我对Windows和Linux的答案感兴趣,但如果有人能解释他们的答案是否特定于一个答案,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

System.nanoTime()可以具有快速的纳秒级分辨率计时器,具体取决于操作系统。在某些操作系统上,这速度可达20 ns。

在这个库中,我使用了RDTSC,因为RHEL 5.x不是那种速度快的操作系统之一。 :( https://github.com/peter-lawrey/Java-Thread-Affinity在快速PC上花费不到10 ns。

使用cpu计数器的问题是它在不同的套接字上有所不同。如果您的程序只在一个套接字上运行,那么这不是问题。

答案 1 :(得分:1)

微基准测试有几个可能被忽视的固有变量

  • 垃圾收集的Java效果
  • JIT优化的Java效果需要一些时间来“预热”
  • Java目标VM
  • Java VM设置(-Xnnnn设置,以及客户端与服务器模式)
  • 目标操作系统差异
  • 目标CPU差异
  • 静止:CPU在背景中多任务处理其他事情
  • 基准代码本身的开销

Caliper Micro-benchmarking framework这样的工具试图解决一些但不是所有上述问题。我甚至不确定它想要做的一切。但至少其主要的显而易见的事情是尝试预热JIT,运行基准代码固定次数并在迭代中取平均值,并重复该练习几次,直到运行之间存在一些可接受的容差。它还捕获并记录环境,以便未来的基准可以比较苹果与苹果(而不是橙子)。它允许您轻松地重复和比较上述所有不同的VM设置或程序参数,并比较每个参数的结果。

尽管如此,它仍然是一项艰巨的冒险尝试,不会误解结果,或者更不可能让别人误解结果。

编辑(加法) 实际上JIT可以削减两种方式。虽然您通常希望JIT得到预热,但它也可以优化您想要包含的内容作为基准测试的一部分。因此,您必须以这样一种方式编写基准,以通过强制每个循环实际上以对您测量的重要/重要的方式变化来预测和防止循环不变量之类的事情被优化掉。