Выполнение участка кода в реальном времени, засекаем время?

Приведу сразу фрагмент кода:

t1 = timeGetTime();
    Device.sendRequest( Command1 );
    R1 = Device.readResponse();

    Device.sendRequest( Command2 );
    R2 = Device.readResponse();
t2 = timeGetTime();
cout << t2-t1 << " ms" << endl;



На некоторое устройство по интерфейсу RS-232 посылаем некоторый запрос, затем дожидаемся ответа и повторяем все еще раз. Для замера времени работы используется Multimedia Timer. Возникает два вопроса:


1) Насколько вообще корректно подобным образом замерять время работы? Данный таймер, как заявляет майкрософт, обеспечивает разрешение 1 мс. В реальных условиях данный код выполняется(по данным этого таймера) за 20..50 мс, и точность этого измерения играет критичную роль в решении задачи.


2) Собственно, главный вопрос. Работаем мы в многозадачной среде. Если прогнать вышеприведенный замер, скажем, 100 раз подряд, в среднем получаются значения 20..30 мс, что более-менее сходится с теоретическими расчетами для данной скорости передачи и длины сообщений. Однако, периодически встречаются выбросы в 50..60 мс, а этот момент имеет принципиальное значение. Если мое предположение верно, где-то в процессе ожидания ответа или перед посылкой второго запроса процесс может быть сочтен ожидающим и планировщик «вклинивает» на выполнение какой-то посторонний процесс. Разумеется, возможно дело в самом оборудовании, но хотелось бы исключить влияние ОС. Собственно, вопрос: подскажите, пожалуйста, грамотный способ: как можно повысить приоритет для данного участка кода, чтобы он выполнялся максимально монопольно, без непредсказуемых задержек со стороны ОС?

У меня сейчас нет возможности попробовать самому, но удалось нагуглить про функции SetPriorityClass() и SetThreadPriority(). Это хотя бы верное направление, поможет решить задачу?
  • Вопрос задан
  • 5372 просмотра
Пригласить эксперта
Ответы на вопрос 5
noonv
@noonv
а разве Windows 7 является системой реального времени? :)
установить более высокий приоритет — да — это чуть поможет, но от переключения контекста не избавит.
если важен RT, то лучше смотреть в сторону RTOS, пробовать Linux с RT-патчем и т.п.
Ответ написан
ntkt
@ntkt
Потомственный рыцарь клавиатуры и паяльника
По поводу таймеров в Windows есть неплохая вводная статья Jan Wassenberg «Timing Pitfalls and Solutions»
github.com/0ad/0ad/raw/master/docs/timing_pitfalls.pdf
Ответ написан
@egorinsk
В windows есть более точные методы измерения времени, например. QueryPerformanceCounter. Чтобы узнать, вытеснялся ли ваш процесс, можно поискать значение какого-нибудь счтечика переключений контекста.
Ответ написан
Комментировать
IlyaEvseev
@IlyaEvseev
Opensource geek
По поводу таймера — уже читали stackoverflow.com/questions/1825720/c-high-precision-time-measurement-in-windows?
Это первая ссылка в Гугле по запросу «windows high resolution timer».

По поводу приоритетов всё написано правильно, тут пишут то же самое.
Найдено Гуглом по запросу «windows change process priority c++».
На многоядерном процессоре максимальный приоритет позволит процессу/потоку получить _почти_ реалтайм.
Если его всё равно окажется недостаточно — тогда останется либо переходить на полноценную(?) RT OS, либо брать WDK и писать собственный драйвер :)
Ответ написан
@vilgeforce
Раздолбай и программист
Как уже написали выше: винда — не Real Time. Второе: последовательный порт, как минимум в XP/2K — штука хитрая и от реализации Device.readResponse может зависеть время. И самый, все-таки, главный вопрос: что вы измеряете? Реальное время от приема посылки до окончания передачи (с точки зрения устройства) или время от передачи до приема на винде? Если первое — светодиод и осцилограф. Если второе — печаль.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы