Я ищу, чтобы улучшить или запросить мой текущий метод задержки / сна.

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

{
    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 ответа


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

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

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

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

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

#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 мс).


Вы можете установить минимальное разрешение таймера 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);

Есть идеи?

10000