Windows精确计时:CreateTimerQueueTimer或system_clock :: now()出错?

时间:2013-01-21 12:38:05

标签: c++ winapi c++11 visual-studio-2012 chrono

我正在努力实现+/- ms的定时精度。我希望线程之间的时间间隔为10毫秒,但是当我测量时间时,我会得到接近15毫秒的东西。

我想知道问题是由于我测量时间的方式,还是我准确测量时间,CreateTimerQueueTimer引入了一些延迟

我的代码看起来像

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <chrono>
#include <ctime>
using namespace std;
int current;
long long* toFill;
void talk()
    {
    chrono::time_point<chrono::system_clock> tp = \
        chrono::system_clock::now();
    toFill[current++]=chrono::duration_cast<chrono::milliseconds>(tp.time_since_epoch()).count() ;
    }

int _tmain(int argc, _TCHAR* argv[])
    {
    HANDLE hTimer;
    current = 0;
    toFill = new long long[1000];
    CreateTimerQueueTimer(&hTimer,NULL, 
        (WAITORTIMERCALLBACK)talk,NULL,
        0,10,0);
    _sleep(3000);
    DeleteTimerQueueTimer(NULL,hTimer,NULL);
    for (int i = 1;i<current;i++)
        {
        cout << i << " : " << toFill[i]-toFill[i-1]<< endl;
        }
    return 0;
    }

输出看起来像

...
161 : 16 <-- Should be 10
162 : 15
163 : 16
164 : 16
...

3 个答案:

答案 0 :(得分:4)

Windows中定时器和实时时钟的精度受时钟滴答中断率的限制。默认情况下,每秒发送64次,1/64秒= 15.625毫秒。就像你看到的一样。

实际上可以提高该速率,在程序开始时调用timeBeginPeriod(10)以获得10毫秒的精确度。

答案 1 :(得分:1)

CreateTimerQueue不适用于精确计时。它使用下面的线程池,这可能会导致严重的延迟。

来自MSDN的CreateTimerQueueTimer function文档:

  

回调函数排队到线程池。这些线程会受到调度延迟的影响,因此时序可能会因应用程序或系统中发生的其他情况而有所不同。

答案 2 :(得分:0)

如果您需要比15毫秒更好的分辨率,那么这将有望帮助:

Implement a Continuously Updating, High-Resolution Time Provider for Windows

(感谢@MaxTruxa了解链接上的更新)

至于测量时间:如果我可以访问Windows或Visual Studio,我会给high_resolution_clock一个镜头。 (我在7年前切换到Linux,抱歉,我自己无法检查。)正如Xeo所写:“high_resolution_clock是带有MSVC的system_clock的typedef。”