Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Windows精确计时:CreateTimerQueueTimer或system_clock::now()中出错?_C++_Winapi_C++11_Visual Studio 2012_Chrono - Fatal编程技术网

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

C++ Windows精确计时:CreateTimerQueueTimer或system_clock::now()中出错?,c++,winapi,c++11,visual-studio-2012,chrono,C++,Winapi,C++11,Visual Studio 2012,Chrono,我正在努力实现+/-ms计时精度。我希望线程之间的时间为10ms,但当我测量时间时,我得到的时间接近15ms 我试图了解问题是由于我测量时间的方式造成的,还是因为我准确地测量时间,并且CreateTimerQueueTimer 我的代码看起来像 #include "stdafx.h" #include <iostream> #include <Windows.h> #include <chrono> #include <ctime> using n

我正在努力实现+/-ms计时精度。我希望线程之间的时间为10ms,但当我测量时间时,我得到的时间接近15ms

我试图了解问题是由于我测量时间的方式造成的,还是因为我准确地测量时间,并且
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;
    }
#包括“stdafx.h”
#包括
#包括
#包括
#包括
使用名称空间std;
电流;
朗朗*托菲尔;
空谈
{
时钟::时间点tp=\
时钟::系统时钟::现在();
toFill[current++]=chrono::duration_cast(tp.time_-since_-epoch()).count();
}
int _tmain(int argc,_TCHAR*argv[]
{
处理hTimer;
电流=0;
toFill=新长长[1000];
CreateTimerQueueTimer(&hTimer,NULL,
(WAITORTIMERCALLBACK)通话,无效,
0,10,0);
_睡眠(3000);
DeleteTimerQueueTimer(NULL,hTimer,NULL);

对于(int i=1;i如果您需要比15 ms更好的分辨率,那么这将有助于:

(感谢链接上的更新)


至于测量时间:如果我可以访问Windows或Visual Studio,我会试一试。(7年前我切换到Linux,对不起,我自己无法检查。)正如Xeo所写:“高分辨率时钟是MSVC系统时钟的typedef。”Windows中计时器和实时时钟的精度受时钟滴答声中断率的限制。默认情况下,时钟滴答声中断率为每秒64次,1/64秒=15.625毫秒。正如您所看到的


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

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

来自MSDN的文件:

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


high_-resolution_-clock
是一个
typedef
用于
system_-clock
的MSVC.:/@Xeo谢谢,我不知道。编辑了相应的答案!链接不再起作用,但文章可以通过访问。@MaxTruxa谢谢,更新了答案,感谢您的帮助!不确定您的意思“Windows中的实时时钟”。可调度计时器确实只与时钟中断一样精确,但可以以更高的精度查询时间。这个建议很好,但我不认为有关时钟精度的说法是正确的。我想了解的问题是,
sleep()
错误,或者如果
clock::now()
错误。当我通过设置
timeBeginPeroid(10)
来增加粒度时,我的睡眠似乎唤醒得更快(类似的带有互斥锁的代码使它们解锁得更快)。这将提示
clock::now()
总是报告正确的时间,并且
sleep()
是造成差异的原因。睡眠时间太长。也许,实现自旋锁可以解决这个问题。我不知道什么是_sleep()。请改用sleep()。无论如何,它应该与通话间隔()无关回调。我不知道你在说什么。我解释了16毫秒的间隔是从哪里来的,以及如何更改它。如果你有一些新问题或“不一致”“那么我猜不出那是什么样子,我从这里看不到你的屏幕。如果你希望精确的10毫秒间隔,那就划掉它,Windows不是实时操作系统。祝你好运。@Mikhail-错误在调用睡眠中。睡眠使用操作系统计时器中断(其间隔在timeBeginPeriod中指定)确定何时唤醒。如果您将计时器中断设置为10毫秒的间隔并调用Sleep(1),您将实际睡眠10毫秒(至少!)
...
161 : 16 <-- Should be 10
162 : 15
163 : 16
164 : 16
...