Я ищу, чтобы улучшить или запросить мой текущий метод задержки / сна. C ++ - PullRequest
0 голосов
/ 10 февраля 2020

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

{
    LONGLONG timerResolution;
    LONGLONG wantedTime;
    LONGLONG currentTime;

    QueryPerformanceFrequency((LARGE_INTEGER*)&timerResolution);
    timerResolution /= 1000;

    QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
    wantedTime = currentTime / timerResolution + ms;
    currentTime = 0;
    while (currentTime < wantedTime)
    {
        QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
        currentTime /= timerResolution;
    }
}

В основном проблема, с которой я сталкиваюсь, заключается в том, что при использовании этой функции используется около 16-20% процессорного времени. Обычный сон (); использует нулевой процессор, но из того, что я прочитал на нескольких форумах, крайне неточно, потому что это компромисс, когда вы обмениваете точность на использование процессора, но я подумал, что лучше поднять вопрос, прежде чем установить этот метод ожидания.

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Можно установить минимальное разрешение таймера Windows (обычно 1 мс), чтобы точность Sleep() составляла до 1 мс. По умолчанию это будет с точностью до 15 мс. Документация Sleep ().

Обратите внимание, что выполнение может быть отложено, если другие программы потребляют процессорное время, но это также может произойти, если вы ожидаете с таймером.

#include <timeapi.h>

// Sleep() takes 15 ms (or whatever the default is)
Sleep(1);

TIMECAPS caps_;
timeGetDevCaps(&caps_, sizeof(caps_));
timeBeginPeriod(caps_.wPeriodMin);

// Sleep() now takes 1 ms
Sleep(1);

timeEndPeriod(caps_.wPeriodMin);
1 голос
/ 10 февраля 2020

Причина, по которой он использует 15-20% ЦП, скорее всего, потому что он использует 100% на одном ядре, поскольку в этом нет ничего, что могло бы замедлить его работу.

В общем, это "сложная" проблема решать как ПК (точнее, ОС, работающие на этих ПК), как правило, не предназначены для запуска приложений реального времени. Если это абсолютно желательно, вам следует изучить ядра и операционные системы реального времени.

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

Если вы используете Linux, вы можете попробовать использовать метод nanosleep (http://man7.org/linux/man-pages/man2/nanosleep.2.html), хотя у меня нет никакого опыта с ним.

В качестве альтернативы вы могли бы go с гибридным подходом, где вы используете режимы сна для длительных задержек, но переключитесь на опрос, когда почти время:

#include <thread>
#include <chrono>
using namespace std::chrono_literals;

...

wantedtime = currentTime / timerResolution + ms;
currentTime = 0;
while(currentTime < wantedTime)
{
    QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
    currentTime /= timerResolution;
    if(currentTime-wantedTime > 100) // if waiting for more than 100 ms
    {
       //Sleep for value significantly lower than the 100 ms, to ensure that we don't "oversleep"
        std::this_thread::sleep_for(50ms); 
    }
}

Теперь это склонно к небольшому состоянию гонки, поскольку предполагается, что ОС вернет управление программой в течение 50 мс после выполнения sleep_for. Для дальнейшей борьбы с этим вы можете выключить его (скажем, спать 1 мс).

...