Как я использую меньше ЦП с циклами?

У меня есть цикл, который похож на это:


while (elapsedTime < refreshRate) 
{
    timer.stopTimer();
    elapsedTime=timer.getElapsedTime();
}

Я считал что-то подобное этому в другом месте (C Основной цикл без 100% CPU), но этот цикл выполняет таймер высокого разрешения, который должен быть точным. Таким образом, как я, как предполагается, не поднимаю 100% ЦП, все еще сохраняя это высоким разрешением?

5
задан Community 23 May 2017 в 12:01
поделиться

4 ответа

Вы не должны ждать, а лучше пусть ОС сообщит вам, когда время истекло.

http://msdn.microsoft.com/en-us/library/ms712704 (VS.85) .aspx

Таймеры с высоким разрешением (более 10 мс)

http://msdn.microsoft. com / en-us / magazine / cc163996.aspx

6
ответ дан 18 December 2019 в 11:52
поделиться

Когда вы говорите, что ваш таймер должен быть «точным», насколько точным вы должны быть на самом деле? Если вам нужно быть точным с точностью до миллисекунды, вы можете добавить полмиллисекундный сон внутри цикла. Вы также можете добавить динамически изменяющийся оператор сна в зависимости от того, сколько времени вам осталось спать. Подумайте о чем-то вроде (псевдокода):

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.

4
ответ дан 18 December 2019 в 11:52
поделиться

Посмотрите на некоторые таймеры, предоставляемые ОС, например POSIX usleep .
С другой стороны, если вам нужна гиперточность, ваш код тоже не будет работать, потому что ОС разорвет этот цикл после того, как исчерпает свой квант времени процесса и перейдет в пространство ядра, чтобы выполнить некоторые системные задачи. Для этого вам понадобится специальная ОС с прерываемым ядром и предоставляемыми ею инструментами; ищите ключевое слово RTOS.

3
ответ дан 18 December 2019 в 11:52
поделиться

Обычно вы тем или иным образом уступаете ОС. Это позволяет ОС отвлечься от вашей программы и заняться чем-нибудь еще.

Очевидно, это зависит от ОС, но:

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

void yield(void)
{
    #ifdef _WIN32
        Sleep(0);
    #else
        usleep(1);
    #endif
}

Вставьте вызов yield перед остановкой таймера. ОС сообщит о меньшем использовании времени вашей программой.

Имейте в виду, конечно, что это делает ваш таймер «менее точным», потому что он может обновляться не так часто, как это возможно. Но не стоит полагаться на крайнюю точность, это слишком сложно. Приближения в порядке.

2
ответ дан 18 December 2019 в 11:52
поделиться
Другие вопросы по тегам:

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