Точная синхронизация Windows: ошибка в CreateTimerQueueTimer или system_clock :: now ()?

Я работаю над достижением +/- мс точности синхронизации. Я хочу, чтобы время между потоками составляло 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
...

1

Решение

Точность таймеров и часов реального времени в Windows ограничена частотой прерывания такта. Что по умолчанию составляет 64 раза в секунду, 1/64 секунды = 15,625 мсек. Так же, как вы видели.

Увеличение этой ставки на самом деле возможно, позвоните timeBeginPeriod (10) в начале вашей программы, чтобы получить точность 10 мсек.

4

Другие решения

CreateTimerQueue не предназначен для точного времени. Под ним используются пулы потоков, что может привести к значительным задержкам.

Из MSDN Функция CreateTimerQueueTimer документ:

Функции обратного вызова ставятся в очередь в пул потоков. Эти потоки подвержены задержкам планирования, поэтому время может меняться в зависимости от того, что еще происходит в приложении или системе.

1

Если вам нужно лучшее разрешение, чем 15 мс, надеюсь, это поможет:

Реализуйте постоянно обновляемый поставщик времени с высоким разрешением для Windows

(Спасибо @MaxTruxa для обновления по ссылке)

Что касается измерения времени: если бы у меня был доступ к Windows или Visual Studio, я бы дал high_resolution_clock выстрел. (Я перешел на Linux 7 лет назад, извините, я сам не могу это проверить.) Как писал Xeo: «high_resolution_clock — это typedef для system_clock с MSVC».

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector