Войти
ПрограммированиеФорумГрафика

Как программно установить ограничение FPS как с включенным V-Sync в Nvidia Control Panel?

Страницы: 1 2 Следующая »
#0
6:34, 27 мар 2018

Встала в полный рост задача ограничить скорость выполнения программы привязав ее к "скорости монитора", то есть если монитор 60 герц - основной цикл должен выполнятся 60 раз в секунду, если монитор 144 герц - 144 раза в секунду.
Много гуглил примеры, использовал Sleep(), std::chrono::high_resolution_clock::now(), std::this_thread::sleep_for() - полноценного нужного эффекта нет, возникают лишние задержки (не из-за тяжести программы, без задержек основной цикл работает 300 раз в секунду).

Мне нужна достичь именно такого эффекта, который дает включенный V-Sync в Nvidia Control Panel.
Когда я использовал std::this_thread::sleep_for() для получения нужной задержки, моя программа сжирала 7-9% процессора, а когда ограничивал скорость с помощью V-Sync из Nvidia Control Panel - программа сжирает всего 1-2% процессора.

Существует ли в С++ какая-нибудь функция, которая говорит программе заснуть пока монитор на начал заново обновлять кадр? Или какие еще есть способы добиться нужного эффекта?

#1
6:49, 27 мар 2018

MikeNew
включи синхронизацию программно

#2
6:51, 27 мар 2018

Aroch
> включи синхронизацию программно
Знать бы еще как.

#3
6:57, 27 мар 2018

В OpenGL это:

wglSwapIntervalEXT(1);

больше ничего не знаю.
Т.е. использовать функцию GAPI, а для не графических программ практического смысла не вижу :)

#4
7:01, 27 мар 2018

Daniil Petrov
> В OpenGL это:
>
> wglSwapIntervalEXT(1);
Спасибо, у меня Вулкан, буду гуглить аналог.

#5
8:19, 27 мар 2018

Нашел, все оказалось предельно просто. Спасибо за наводку. Тему можно закрыть, если темы тут закрывают.

#6
8:30, 27 мар 2018

MikeNew
обычно в таких случаях принято писать, что за решение ты в итоге использовал, чтобы будущим поколениям была какая-то польза от твоего треда. судя по всему, это что-то вроде VK_PRESENT_MODE_FIFO_KHR, но всё равно.

#7
8:59, 27 мар 2018

Suslik
> обычно в таких случаях принято писать, что за решение ты в итоге использовал,
> чтобы будущим поколениям была какая-то польза от твоего треда. судя по всему,
> это что-то вроде VK_PRESENT_MODE_FIFO_KHR, но всё равно.
Я поэтому и не написал, потому что знаю, что всем все равно - все в юнити сидят, что-то делать сами ручками никто больше не хочет. :D
И да, это именно  VK_PRESENT_MODE_FIFO_KHR.

#8
17:14, 27 мар 2018

MikeNew
> Я поэтому и не написал, потому что знаю, что всем все равно - все в юнити
> сидят, что-то делать сами ручками никто больше не хочет. :D
Вот не надо, пожалуйста, вот так вот обобщать. :<
Ну и вообще, если ни у кого другого не возникнет твоей проблемы, от твоего ответа не будет ни холодно ни жарко. Если у кого-то возникнет - будет лучше оставить ему ответ, чтобы не пришлось по-новой создавать треды с тем же вопросом. Так что в общем случае, лучше оставить ответ, чем не оставить.

#9
21:59, 27 мар 2018

Как программно установить ограничение FPS как с включенным V-Sync в Nvidia Control Panel?

Цель VSync не ограничить FPS, а синхронизировать вывод кадра с монитором - что приводит и к ограничение количества кадров, но как следствие.
Приложение может управлять VSync самостоятельно, но пользователь всё равно может отключить его соответствующей настройкой в панели драйвера NVIDIA / AMD.
Так что если цель - добиться ограничения FPS сверх некоторой нормы, то необходимо всё-равно этим озадачится.

Впрочем, основная задача Sleep() в цикле рендерера вовсе не ограничение FPS, а освобождение CPU (чтобы он не шпарил на 100% без толку) и, как дополнительный эффект, ограничение FPS (точнее говоря Sleep становится инструментом целевой функции желаемого FPS).
Стоит учесть, что Sleep() имеет плохую точность по-умолчанию в Windows, которая повышается с помощью timeBeginPeriod (которая влияет на ВСЕ приложения в системе, а не только на то, в котором её позвали).

Ну и для получения желаемого FPS необходимо калибровать время Sleep() динамически, увеличивая и уменьшая его в зависимости от нагрузки и производительности системы.

#10
22:36, 27 мар 2018

gkv311
> Стоит учесть, что Sleep() имеет плохую точность по-умолчанию в Windows, которая
> повышается с помощью timeBeginPeriod (которая влияет на ВСЕ приложения в
> системе, а не только на то, в котором её позвали).
Ну как бы Sleep() - это скорее "моему потоку делать категорически нечего, и в ближайшем будущем (определённой степени близости) работы не предвидится", так что особая точность там и не нужна.

#11
6:13, 28 мар 2018

Delfigamer

Ну как бы Sleep() - это скорее "моему потоку делать категорически нечего, и в ближайшем будущем (определённой степени близости) работы не предвидится", так что особая точность там и не нужна.

Ну как бы если время кадра ~16 ms (при 60 кадрах в секунду, при 144 будет уже меньше), а Sleep(1) проснётся через ~14 ms, то вашему движку останется всего 2 ms для обработки.
Не думаю, что нормальному 3D приложению хватит 2 ms - соответственно 60 FPS вы не получите.
Так было во времена старых Windows, на Win10 я не перепроверял (код написан давно), может Microsoft наконец-то исправила эту глупость (в Unix/Linux такого не было).

#12
7:21, 28 мар 2018

gkv311
> Цель VSync не ограничить FPS, а синхронизировать вывод кадра с монитором - что
> приводит и к ограничение количества кадров, но как следствие.
Просто у меня сложилось впечатление что именно этот способ оказался самым полноценным, несмотря на то что он всего лишь "следствие".
С другой стороны, конечно более универсальный способ действительно может понадобится, к примеру в случае тех же 144-герцовых мониторов. Значит буду дальше играться с std::this_thread::sleep_for() и с std::chrono::, они хоть дает возможность с микросекундами работать.

#13
7:58, 30 мар 2018

Кстати в DX вопрос Vsync не такой тривиальный. Точнее если надо синхронизировать по Preset(), то проблем нет (хотя есть специфика, скажем на LiquidVR), но если надо ловить Vsync дабы синхронизировать треды, то тогда приходится действовать через:
SwapChain->GetContainingOutput(&s_Monitor);
s_Monitor->WaitForVBlank();
Потенциально у вас может быть несколько карт и мониторов.

#14
9:20, 30 мар 2018

Забавный момент (кстати, наблюдал его в куче игр) - если свернуть окно, то фпс взлетает до небес () и, похоже, видеокарта загружается по полной (процессор точно полностью загружается).

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.