根据 CPU 时钟测量时间



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

通常在Java中,我会使用:

System.nanoTime()

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

是否有任何 Java 等效代码可以根据 CPU 来测量时间,或者必须使用某种 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的答案感兴趣,但如果人们能解释他们的答案是否特定于一个,我将不胜感激。

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

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

使用 cpu 计数器的问题在于它在不同的插槽上是不同的。如果您的程序仅在一个套接字上运行,这不是问题。

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

  • 垃圾回收的爪哇效应
  • JIT优化的Java效果,需要一些时间来"预热"
  • Java 目标虚拟机
  • Java VM 设置(-Xnnnn 设置,以及客户端与服务器模式)
  • 目标操作系统差异
  • 目标 CPU 差异
  • 静止:CPU 在后台多任务处理其他事情的繁忙程度
  • 基准代码本身的开销

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

也就是说,不误解结果,

或者更有可能不让其他人误解结果,仍然是一个棘手的危险 - 充满危险的努力。

编辑(添加)实际上,JIT可以双向切割。 虽然您通常希望预热 JIT,但它也可以优化要作为基准测试的一部分包含的内容。 因此,您必须以这样一种方式编写基准测试,以预测并防止诸如循环不变量之类的事情被优化,方法是强制每个循环实际上以对您正在测量的内容重要/重要的方式变化。

最新更新