Страница 1 из 3

Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 15.08.2020 21:55:15
Seenkao
Всем привет. Наверняка многим известно, что я занимаюсь доработкой ZenGL и я давно ещё искал путь ограничения ФПС, ещё задолго до того как начал заниматься самим ZenGL.
И вот, разбираясь что к чему и получив ограничение которое искал, я обнаружил, что очень сильно стал загружаться процессор, аж до 25%... в чём же дело? И стал ковырять код дальше, сначала подумав, что может где-то не то наковырял...

Так вот, слишком долгое вступление. :)

Описываю внутренний цикл, в котором идёт опрос самой системы PeekMessageW и зачастую после этого опроса заставляют работать саму программу.
Итак, опросили систему и запустили свой цикл
Код: Выделить всё
var
  newTime, oldTime: Double;
  maxFPS: single = 1000 / 30;      // 30 FPS - ограничиваем
...
if winON then
begin
  if PeekMessage(...) then
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end
  else begin    // основной опрос вашей программы
    newTime := GetTickCount;
    // выставляем (проверяем) ограничение
    if newTime >= oldTime + maxFPS then
    begin
      Draw();                          // стандартная работа программы
      oldTime := oldTime + maxFPS;
      ...
    end

// и вот тут код, который вдруг разгружает систему почти в нуль,
    else
      Sleep(1);
  end;
end;
...


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

P.S. нашёл ошибку, исправил )))) в том коде что выложил.

P.P.S. Касается в основном Windows.

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 15.08.2020 22:41:47
runewalsh
while true do PeekMessageW — крутится столько раз в секунду, сколько сможет, и занимает 1 ядро процессора вплоть до 100%, совсем как while true do inc(i).
Sleep — говорит системе снять твой поток с выполнения на указанное время, освободив ядро процессора для других потоков, а если работы нет — усыпив его.
Спящее ядро не потребляет энергию, не греется и учитывается как 0% нагрузка. Собственно, в каждый момент времени ядро либо делает что-то и тем самым загружено на 100%, либо спит и загружено на 0%, промежуточные показатели, которые ты видишь — усреднённое состояние в течение некоторого времени, например, 1 секунды.

Но while true do begin PeekMessageW(...); Sleep(1); end; — отвратительное решение, подробнее в этой статье. Вкратце: если бы каждая запущенная в твоей системе программа крутилась в цикле, в котором она засыпает на 1 миллисекунду, просыпается, что-то проверяет и снова засыпает — то на ней можно было бы жарить яичницу, даже когда ничего не запущено.
Правильно: while true do begin GetMessageW(...); ... end;
GetMessageW, если сообщений нет, сама усыпит поток и разбудит, когда придёт сообщение. Если при этом нужно уметь будить его и самостоятельно — можно использовать MsgWaitFor*-ожидания или пользовательские оконные сообщения WM_APP+x (ими можно будить спящую GetMessageW).
В крайнем случае спать нужно не 1 миллисекунду, а max(0, 1 / maxFpms - passed).

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 15.08.2020 23:06:54
Seenkao
Вкратце: если бы каждая запущенная в твоей системе программа крутилась в цикле, в котором она засыпает на 1 миллисекунду, просыпается, что-то проверяет и снова засыпает — то на ней можно было бы жарить яичницу, даже когда ничего не запущено.

Это предотвращается программно.

Правильно: while true do begin GetMessageW(...); ... end;

я думаю не стоит говорить "правильно" или "не правильно" использовать те или иные функции, не зная как работает программа.

Но теперь вопрос появляется, есть ли аналог Sleep? И твой пост заставляет задуматься!!! :)

P.S. И, надо понимать, что в данном случае Sleep(1) "подменяет" прорисовку экрана (а может ещё какой код), если мы не вышли на время прорисовки, а не сопровождает код прорисовки.

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 16.08.2020 21:15:36
olegy123
Seenkao писал(а):Я не знаю, знают об этом или нет, но я ни где не видел, чтоб так можно было разгрузить систему. Получается, если мы не прорисовываем ни чего, то заставляем процессор выждать милисекунду.
Это вообще правильно?

Можно, и в некоторых случаях правильно и просто. Есть приложения которые работают по запросу - практически все гуи приложения, иначе калькулятор грузил проц на все 100.
Но в других лучше так не использовать, потому что на 1ms теряешь управление. 1ms это очень много.

Кстати еще выход снизить нагрузку - это уменьшить приоритет потока.

Добавлено спустя 11 минут 8 секунд:
Seenkao писал(а):Но теперь вопрос появляется, есть ли аналог Sleep?
смотришь на системы реального времени? где требуется жесткий регламент таймеров?
В линухе само ядро работает на 1Кгц это максимум что можегешь получить по переключениям, с учетом того что тебе никто не будет мешать..
если хочешь иметь импульсы повыше -их можно извне.. смотри в сторону STM32/FPGA

Добавлено спустя 4 минуты 9 секунд:
В винде есть счетчик тактов по процессору, но он от процика к процику разный.

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 16.08.2020 23:01:51
Seenkao
olegy123 писал(а):Можно, и в некоторых случаях правильно и просто. Есть приложения которые работают по запросу - практически все гуи приложения, иначе калькулятор грузил проц на все 100.
Но в других лучше так не использовать, потому что на 1ms теряешь управление. 1ms это очень много.

Благодарю! Я понял и данная проблема решена и для меня подходит.
Если я использую цикл и PeekMessage, то использую Sleep, а если работаю от системы используя GetMessage, то от Sleep надо отказываться.

Добавлено спустя 4 минуты 5 секунд:
Seenkao писал(а):смотришь на системы реального времени? где требуется жесткий регламент таймеров?
В линухе само ядро работает на 1Кгц это максимум что можегешь получить по переключениям, с учетом того что тебе никто не будет мешать..
если хочешь иметь импульсы повыше -их можно извне.. смотри в сторону STM32/FPGA

Добавлено спустя 4 минуты 9 секунд:
В винде есть счетчик тактов по процессору, но он от процика к процику разный.

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

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 17.08.2020 07:03:03
olegy123
Когда я был не опытен, я пытался у гуи повысить fps
но уперся в то что нужно рисовать пикселями и винда еще должна перегрузить все художества на экран. Существующие технологии не позволяют моим фантазиям шагать широко.
Пришлось изучать GPU

В GPU нужно загрузить материал, схемы расчеты что и как строить. Он сам начнет строить. CPU работает только на подхвате, поэтому вполне может подольше поспать.

Добавлено спустя 11 минут 17 секунд:
с проблемой точного подсчета времени я столкнулся когда нужно было синхронизировать работу двух компьютеров, штатных средств нет.
Ethernet не самый быстрый синхронизатор. там пакет уходит когда микросхема решит сбросить буфер, и наоборот, известить CPU о входящих пакетов.

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 17.08.2020 12:10:35
mig-31
Seenkao писал(а):Всем привет. Наверняка многим известно, что я занимаюсь доработкой ZenGL и я давно ещё искал путь ограничения ФПС, ещё задолго до того как начал заниматься самим ZenGL.
И вот, разбираясь что к чему и получив ограничение которое искал, я обнаружил, что очень сильно стал загружаться процессор, аж до 25%... в чём же дело? И стал ковырять код дальше, сначала подумав, что может где-то не то наковырял...


У меня есть приложение для Линух, в кoтором у меня в 2-х TThread крутится в циклах опрос двух устройств по последовательному порту и Telnet без sleep. Загрузки процесора на 25% я не наблюдаю.
olegy123 писал(а):В линухе само ядро работает на 1Кгц это максимум что можегешь получить по переключениям, с учетом того что тебе никто не будет мешать..
если хочешь иметь импульсы повыше -их можно извне.. смотри в сторону STM32/FPGA

Немного исправлю. Ядра по умолчанию, коплирируются на 1кГц и этого достаточно для большинства задач. Для мультимедия этого мало, поэтому есть возможность собрать ядро с таймером 1МГц и почти во всех дистрибутивах оно есть в репозитории. Есть также патч реального времени для ядра (soft realtime).

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 17.08.2020 12:56:18
Seenkao
Ответ на первоначальный вопрос, касается он больше Windows (на Linux не надо ни чего придумывать), Sleep(1) можно использовать только для прорисовки кадров не более 60Гц. Как только мы увеличиваем граничную частоту больше 60, есть достаточный шанс, что приложение начнёт лагать. Для небольших процессов это возможно не критично, но для приложений, граничащих по работе с частотой обновления монитора, наверняка вызовет глюки.

Sleep(1), может вызвать задержку до 16 милисекунд. (что для 60 Гц как раз и не критично).

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 17.08.2020 18:23:57
скалогрыз
Seenkao писал(а): Наверняка многим известно, что я занимаюсь доработкой ZenGL и я давно ещё искал путь ограничения ФПС

Код: Выделить всё
scr_SetVSync(true);

?

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 17.08.2020 19:38:59
Seenkao
скалогрыз, наверно всё-таки стоит знать как работает внутренний код. Тот метод, по ограничению FPS, не следит за тем, отправляются данные на видеокарту или нет. На системное FPS, ни как не повлияет. А меня интересует, чтоб программа могла спокойно работать не только на последних супер-мощных компьютерах, но и на тех компьютерах, которые "вышли из моды" - устаревшие модели.
И ваше предложение ни как не решит проблем связанных со старыми компьютерами. :)

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 17.08.2020 20:34:44
скалогрыз
Seenkao писал(а): А меня интересует, чтоб программа могла спокойно работать не только на последних супер-мощных компьютерах, но и на тех компьютерах, которые "вышли из моды" - устаревшие модели.

я боюсь, что ZenGL может спокойно работать не только на тех кто "вышли из моды", но даже на тех моделях, которые "вышли из жизни".

ты можешь объяснить, какие такие тормоза будут, если пограмма умудряется выдавать очень большой FPS?

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 18.08.2020 00:24:20
Seenkao
Изображение может дёргаться. Надо будет подгонять кадры, а это хуже некуда.

Я буду обходить этот момент. Просто введу проверку что если ФПС больше 60, то Sleep(1) срабатывать вообще не будет. И это так же будет полезно и для слабых компьютеров, случайный заход на долгую задержку будет исключён.

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

скалогрыз писал(а):я боюсь, что ZenGL может спокойно работать не только на тех кто "вышли из моды", но даже на тех моделях, которые "вышли из жизни".

Не на всех будут. Только на моделях у которых видеокарта поддерживает OpenGL и на компьютерах где OpenGL не поддерживает ***ChoisePixelFormat надо делать доработку на проверку данной функции.

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 18.08.2020 15:39:31
MysticCoder
Похоже, что TC сам придумал себе несуществующие проблемы и сам же пытается их героически преодолеть. Еще рассмотри разницу между Sleep(0) и Sleep(1).

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 18.08.2020 20:31:24
Seenkao
MysticCoder, не существующую? :)
Может вы мне тогда объясните разницу в том, что игры на старых компьютерах потребляют почти всё процессорное время, а при вводе данного кода, те же компьютеры почти бездействуют, но вывод и работа программы осуществляется в том же режиме?!

Я бы очень хотел посмотреть на то как вы справляетесь с этой проблемой.

Re: Нативные приложения - снятие нагрузки?

СообщениеДобавлено: 19.08.2020 01:10:56
MysticCoder
Sleep это легальный способ и его не использует разве только ленивый. Если делать приложению нечего, то логично отдать управление ОС, что и делает Sleep. Загрузка процессора это не что то волшебное, нельзя сказать, что вот эта процедура загружает процессор на 17 процентов, потому что я ее оптимизировал. Пока работает процедура она загружает проц на 100 процентов, если конечно же она не передаёт управление ОС внутри себя всякими блокирующими операциями типа чтений файлов или сокетов.
Если не передавать управление ОС, то загрузка будет 100 процентов. Если передавать управление ОС, то загрузка будет от 0 до 100 процентов.
При 0 рендер и код логики выполняются за пренебрежительно малое время(да-да, старые игры реально могут тратить очень мало процессорного времени). При 100 процентах рендер или/и логика занимают ощутимое время по сравнению со временем потраченным на Sleep.
Велосипедов из сообщений и прочего на замену Sleep городить не надо. Если критичны микросекунды, то не отдаешь управление ОС и миришься со 100 процентной загрузкой проца. Если не критичны, то юзаешь Sleep и спишь спокойно.
Ну и разницу между Sleep(0) и Sleep(1) все таки нагугли.