我已经阅读了一些低延迟技术论文,他们通过CPU测量时序,因为它更准确。
通常在Java中我会使用:
System.nanoTime()
并且在C ++中我相信我曾经使用过一种性能计数器方法,我在网上发现它可以精确到纳秒。它使用了一个LARGE_INTEGER,分配给你想要测量的精度,然后通过引用传递给QueryPerformanceCounter()并返回一个除以频率的答案。
是否存在根据CPU测量时间的Java等效代码,或者是否必须使用某种PInvoke?
编辑:
要达到这种精度水平,必须使用时间戳 来自CPU的计数器。我们选择了具有不变TSC的CPU,因为 较旧的处理器由于省电而受到频率变化的影响 和睡眠状态。
我对Windows和Linux的答案感兴趣,但如果有人能解释他们的答案是否特定于一个答案,我将不胜感激。
答案 0 :(得分:2)
System.nanoTime()可以具有快速的纳秒级分辨率计时器,具体取决于操作系统。在某些操作系统上,这速度可达20 ns。
在这个库中,我使用了RDTSC,因为RHEL 5.x不是那种速度快的操作系统之一。 :( https://github.com/peter-lawrey/Java-Thread-Affinity在快速PC上花费不到10 ns。
使用cpu计数器的问题是它在不同的套接字上有所不同。如果您的程序只在一个套接字上运行,那么这不是问题。
答案 1 :(得分:1)
微基准测试有几个可能被忽视的固有变量
像Caliper Micro-benchmarking framework这样的工具试图解决一些但不是所有上述问题。我甚至不确定它想要做的一切。但至少其主要的显而易见的事情是尝试预热JIT,运行基准代码固定次数并在迭代中取平均值,并重复该练习几次,直到运行之间存在一些可接受的容差。它还捕获并记录环境,以便未来的基准可以比较苹果与苹果(而不是橙子)。它允许您轻松地重复和比较上述所有不同的VM设置或程序参数,并比较每个参数的结果。
尽管如此,它仍然是一项艰巨的冒险尝试,不会误解结果,或者更不可能让别人误解结果。
编辑(加法) 实际上JIT可以削减两种方式。虽然您通常希望JIT得到预热,但它也可以优化您想要包含的内容作为基准测试的一部分。因此,您必须以这样一种方式编写基准,以通过强制每个循环实际上以对您测量的重要/重要的方式变化来预测和防止循环不变量之类的事情被优化掉。