高分辨率性能计数器的解释以及它与.NET Stopwatch的关系存在是什么?

10

在静态Stopwatch构造函数内,我们可以看到以下代码,基本上检查是否存在高分辨率性能计数器。

static Stopwatch()
{
    if (!SafeNativeMethods.QueryPerformanceFrequency(out Frequency))
    {
        IsHighResolution = false;
        Frequency = 0x989680L;
        tickFrequency = 1.0;
    }
    else
    {
        IsHighResolution = true;
        tickFrequency = 10000000.0;
        tickFrequency /= (double) Frequency;
    }
}

在 MSDN 上关于 QueryPerformanceFrequency 的说明是:

检索高分辨率性能计数器的频率,如果存在,则检索该频率。

然而,这个描述并不是很清晰,它到底什么时候存在?我怀疑现在的大多数机器上都存在,但是到底什么情况下不存在呢?

这很有意思,因为当它不存在时,Stopwatch 就变成了一个简单地封装了 DateTime.UtcNow 属性的类。


2
我还没有遇到过不存在这个问题的机器。我面临的主要实际问题是由于有缺陷的硬件引起的行为错误。例如,当线程在不同的核心上调度时,时间可能会向前/向后跳动。 - CodesInChaos
3
在Windows Mobile中它是可选的,取决于平台构建者是否实现它。 - Hans Passant
这个类的“IsHighResolution”和“Frequency”属性应该能够回答这个问题。注意:我在一个虚拟机中[VMWare ESX,但不记得版本]发现了一个零频率,它已经不再出现了[这台机器从w2k3迁移到了w2k8,所以可能是VMWare或Windows :-) ]。 - mabra
2个回答

5
计时器和秒表之间有区别,混淆两者会导致错误的假设。不幸的是,“计时器”这个术语经常被用来表示多种含义。
任何运行Windows 2000或更高版本的机器都可能有高频计时器。我从未遇到过没有此类东西的运行Windows 2000及以上版本的计算机。
那就是高频计时器。还有计时器:Windows或.NET组件。这些计时器不用于计时或测量时间,而是用于定期执行操作。Windows计时器对象能够达到1毫秒的分辨率,并且在计算机不涉及CPU密集型操作时非常可靠。.NET计时器对象的分辨率限制在约15毫秒左右。您可以通过使用P/Invoke与Windows对象直接交互来解决这个问题,但通常情况下不需要这样做。
.NET Stopwatch类基于高频计时器。一般来说,Start查询性能计数器并存储该值。当你Stop时,它再次查询性能计数器。经过时间是这两个值的简单减法。您可以从秒表中获得比微秒更好的分辨率。
事实上,您可以使用一个带有繁忙等待循环的Stopwatch,它可以给您提供亚毫秒级的分辨率。我怀疑您无法获得亚微秒级的分辨率。
重要的是要理解,尽管计时器在1毫秒以上不可靠,但测量经过时间的秒表要精确得多。您可以相信从秒表中获得微秒级别的经过时间测量。除此之外,我就不指望了。

1

系统时间的实际分辨率大约在毫秒级别(即使声称是1/10毫秒,我从未见过可靠提供该分辨率的工作站)。

但是,您可以使用其他硬件(如时间码读取器),其分辨率可达到纳秒级别。这些通常与IPC(工业PC)一起用于工业控制系统中以同步DAQ硬件。您可以在PCI Express插槽卡。PCI Express低档x1本地总线的时间码处理器中看到具有100 ns分辨率的示例。

普通工作站几乎总是使用高分辨率计数器,但实际分辨率不会像您预期的那样(微秒或纳秒),除非使用其他硬件。


我正在寻找所有新机器中高精度计时器,其分辨率在纳秒级别。在VMWare社区中有一篇有趣的白皮书[可能是由VMWare自己撰写],其中解释了哪些计时器被模拟以及如何模拟。br++mabra - mabra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接