У меня есть цикл, который похож на это:
while (elapsedTime < refreshRate)
{
timer.stopTimer();
elapsedTime=timer.getElapsedTime();
}
Я считал что-то подобное этому в другом месте (C Основной цикл без 100% CPU), но этот цикл выполняет таймер высокого разрешения, который должен быть точным. Таким образом, как я, как предполагается, не поднимаю 100% ЦП, все еще сохраняя это высоким разрешением?
Вы не должны ждать, а лучше пусть ОС сообщит вам, когда время истекло.
http://msdn.microsoft.com/en-us/library/ms712704 (VS.85) .aspx
Таймеры с высоким разрешением (более 10 мс)
http://msdn.microsoft. com / en-us / magazine / cc163996.aspx
Когда вы говорите, что ваш таймер должен быть «точным», насколько точным вы должны быть на самом деле? Если вам нужно быть точным с точностью до миллисекунды, вы можете добавить полмиллисекундный сон внутри цикла. Вы также можете добавить динамически изменяющийся оператор сна в зависимости от того, сколько времени вам осталось спать. Подумайте о чем-то вроде (псевдокода):
int time_left = refreshRate - elapsedTime;
while (time_left > 0) {
if (time_left > threshhold)
sleep_for_interval(time_left / 2);
update_timestamp(elapsedTime);
time_left = refreshRate - elapsedTime;
}
С этим алгоритмом ваш код будет засыпать короткими всплесками, если обнаружит, что вам еще нужно подождать. Вы можете запустить несколько тестов, чтобы найти оптимальное значение для порога
, которое уравновешивает экономию использования ЦП с учетом риска перерегулирования (вызванного тем, что ваше приложение теряет ЦП, когда оно спит, и не получает больше процессорного времени во времени) .
Другой метод синхронизации с высоким разрешением - использование аппаратного таймера, который запускает периодическое прерывание. Ваш обработчик прерывания отправит сигнал некоторому потоку, что ему нужно проснуться и что-то сделать, после чего он снова перейдет в спящий режим и ожидает поступления следующего сигнала.
В операционных системах реального времени есть способы сделать это вроде вещей, встроенных в ОС. Если вы занимаетесь программированием для Windows и вам нужна чрезвычайно точная синхронизация, имейте в виду, что это не то, с чем хорошо справляется ОС общего назначения, такая как Windows.
Посмотрите на некоторые таймеры, предоставляемые ОС, например POSIX usleep
.
С другой стороны, если вам нужна гиперточность, ваш код тоже не будет работать, потому что ОС разорвет этот цикл после того, как исчерпает свой квант времени процесса и перейдет в пространство ядра, чтобы выполнить некоторые системные задачи. Для этого вам понадобится специальная ОС с прерываемым ядром и предоставляемыми ею инструментами; ищите ключевое слово RTOS.
Обычно вы тем или иным образом уступаете ОС. Это позволяет ОС отвлечься от вашей программы и заняться чем-нибудь еще.
Очевидно, это зависит от ОС, но:
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void yield(void)
{
#ifdef _WIN32
Sleep(0);
#else
usleep(1);
#endif
}
Вставьте вызов yield перед остановкой таймера. ОС сообщит о меньшем использовании времени вашей программой.
Имейте в виду, конечно, что это делает ваш таймер «менее точным», потому что он может обновляться не так часто, как это возможно. Но не стоит полагаться на крайнюю точность, это слишком сложно. Приближения в порядке.