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

Mik*_*ail 2 c++ winapi c++11 c++-chrono visual-studio-2012

我正在努力实现 +/- 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;
    }
Run Code Online (Sandbox Code Playgroud)

输出看起来像

...
161 : 16 <-- Should be 10
162 : 15
163 : 16
164 : 16
...
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 5

Windows 中的计时器和实时时钟的准确性受到时钟滴答中断率的限制。默认情况下,每秒 64 次,1/64 秒 = 15.625 毫秒。就像你看到的那样。

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

  • 我只是不知道你在说什么。我解释了 16 毫秒间隔的来源以及如何更改它。如果您有一些新问题或有“差异”,那么我无法猜测它是什么样子,我无法从这里看到您的屏幕。如果您希望*精确* 10 毫秒的时间间隔,那么请从头开始,Windows 不是实时操作系统。祝你好运。 (2认同)
  • @Mikhail - 错误在于调用 Sleep。Sleep 使用 OS 定时器中断(其间隔在 timeBeginPeriod 中指定)来确定何时唤醒。如果您将定时器中断设置为 10 毫秒间隔并调用 Sleep(1) 您实际上将睡眠 10 毫秒(至少!) (2认同)