Win7和Win之间的定时器差异Win10

时间:2016-04-18 14:25:40

标签: c++ c++11 windows-7 mingw windows-10

我有一个应用程序,我使用gettimeofday的MinGW实现来实现"精确" Win7上的时序(约1ms精度)。它工作正常。

然而,当在Win10上使用相同的代码(甚至相同的* .exe)时,精度会急剧下降到着名的15.6ms精度,这对我来说还不够。

两个问题: - 你知道这些差异的根源是什么吗? (它是OS配置/"功能"?) - 我该如何解决?或者,更好的是,是否存在与OS配置无关的精确定时器?

注意:std::chrono::high_resolution_clock似乎有同样的问题(至少它确实显示了Win10的15.6ms限制)。

1 个答案:

答案 0 :(得分:1)

从Hans Passant的评论和我身边的其他测试中,这是一个更健全的答案:

Windows上的15.6ms(1/64秒)限制为well-known,是默认行为。虽然我们不建议这样做,但可以降低限制(例如通过调用timeBeginPeriod()来降低1ms),因为这会影响全局系统计时器分辨率和结果power consumption。例如,Chrome is notorious for doing this‌​。因此,由于定时器分辨率的全局性,由于第三方程序,人们可能会在没有明确要求的情况下观察到1ms的精度。

此外,请注意std::chrono::high_resolution_clock 在Windows上具有有效行为(在Visual Studio或MinGW上下文中)。因此,您不能指望此接口是跨平台解决方案,并且仍然适用15.625ms限制。

知道了,我们如何处理它?好吧,可以使用timeBeginPeriod()来提高某些计时器的精确度,但同样,我们不建议这样做:使用QueryPerformanceCounter()(QPC)似乎更好据微软称,这是本机代码期待acquire high-resolution time stamps or measure time intervals的主要API。请注意GPC does count elapsed time (and not CPU cycles)。这是一个用法示例:

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

根据Microsoft,QPC也适用于多核/多线程上下文,但它可能不太精确/模糊:

  

当您比较从不同线程获取的性能计数器结果时,请考虑相差±1的值,以使其具有不明确的排序。如果时间戳是从同一个线程中获取的,则该±1刻度不确定性不适用。在此上下文中,术语tick表示等于1÷的时间段(从QueryPerformanceFrequency获得的性能计数器的频率)。

作为额外资源,MS还会在FAQ on how/why use QPC上提供clock/timing in Windows和解释。