鉴于Stopwatch
C# 中的类可以在下面使用三个不同的计时器,例如
- 系统定时器例如精度约
+-10 ms
取决于可以设置的定时器分辨率timeBeginPeriod https://msdn.microsoft.com/en-us/library/windows/desktop/dd757624(v=vs.85).aspx它可以是大约+-1 ms
.
- 时间戳计数器 (TSC) 例如节拍频率为 2.5MHz 或 1 个节拍 =
400 ns
理想情况下是这样的精确度。
- 高精度事件计时器 (HPET)节拍频率为 25MHz 或 1 个节拍 =
40 ns
理想情况下是这样的精确度。
我们如何衡量其可观测精度?精度定义为
精度是指两个或多个测量值之间的接近程度
其他。
现在如果Stopwatch
使用 HPET 这是否意味着我们可以使用Stopwatch
获得与计时器频率相当的精度测量值?
我不这么认为,因为这要求我们能够使用零方差或完全固定开销的计时器,据我所知,这对于Stopwatch
。例如,当使用 HPET 并调用时:
var before_ticks = Stopwatch.GetTimestamp();
var after_ticks = Stopwatch.GetTimestamp();
var diff_ticks = after_ticks - before_ticks;
那么差异大约是100 ticks
or 4000 ns
它也会有一些差异。
那么如何通过实验来测量可观测精度呢?Stopwatch
?所以它支持下面所有可能的计时器模式。
我的想法是搜索最小刻度数!= 0,首先建立以刻度为单位的开销Stopwatch
对于系统计时器来说,这将是 0,直到例如10ms
这是 10 * 1000 * 10 = 100,000 滴答,因为系统定时器的滴答分辨率为100ns
,但精度远非如此。对于 HPET,它永远不会是 0,因为调用的开销Stopwatch.GetTimestamp()
高于定时器的频率。
但这并没有说明我们可以使用计时器进行测量的精确度。我的定义是我们可以可靠地测量刻度差异有多小。
可以通过测量不同的迭代次数来执行搜索:
var before = Stopwatch.GetTimestamp();
for (int i = 0; i < iterations; ++i)
{
action(); // Calling a no-op delegate Action since this cannot be inlined
}
var after = Stopwatch.GetTimestamp();
首先,可以找到一个下限,其中给定数量的所有测量值都为 10 次iterations
产生非零的刻度数,将这些测量值保存在long ticksLower[10]
。然后产生刻度差的最接近的可能迭代次数始终高于可以找到的前 10 个测量值中的任何一个,将它们保存在long ticksUpper[10]
.
最坏情况下的精度将是最高的刻度ticksUpper
减去最低报价ticksLower
.
这听起来合理吗?
为什么我想知道可观测精度Stopwatch
?因为这可用于确定您需要测量的时间长度,以获得一定程度的微基准测量精度。 IE。对于 3 位精度,长度应 > 计时器精度的 1000 倍。当然,这个长度可以测量多次。