2

我正在努力实现 +/- 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
...
4

3 回答 3

5

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

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

于 2013-01-21T13:04:55.210 回答
1

CreateTimerQueue 并不意味着精确计时。它在下面使用线程池,这可能会引入明显的延迟。

来自 MSDN 的CreateTimerQueueTimer 函数文档:

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

于 2013-06-28T15:33:12.390 回答
0

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

为 Windows 实施持续更新的高分辨率时间提供程序

(感谢@MaxTruxa对链接的更新)

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

于 2013-01-21T12:55:37.230 回答