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

Откуда берутся микрофризы и как с ними бороться?

#0
(Правка: 23 июля 2021, 18:56) 21:14, 22 июля 2021

В игре возникает медленный фрейм с включёным VSYNC, который длится более 18.51 миллисекунд, хотя игра в релизной сборке выдаёт по 400 или 1000 фпс - там не может быть таких медленных фреймов. Я не знаю откуда берутся эти микролаги, ведь обновление игрового состояния и рендер не тормозят. Использую 2D OpenGL и получаю время через таймеры в GLFW, синхронизация через glfwSwapInterval(1). Почему-то без синхронизации микролага нет и в дебаг сборке, которая выдаёт по 300 фпс, тоже нет лага.
Это бы не было проблемой, но в моей игре есть адаптивное упрощение графики, которое включается, когда фпс ниже 50. Микрофризы включают это упрощение даже когда ничего не тормозит. Я уже пробовал снизить порог с 50 до 40 фпс или брать среднее значение времени 4-х и более фреймов, но микролаг всё равно возникает и запускает упрощение графики. Упрощение графики заключается в поочерёдном мигании спрайтов (так делали в играх на игральных автоматах) и выключении некоторых эффектов.

Тема закрыта
Ещё я обнаружил что вызов glFinish перед glfwSwapBuffers убирает микрофризы, но снижает максимальный фпс с 1100 до 650


#1
(Правка: 21:26) 21:20, 22 июля 2021

https://m.habr.com/en/company/pixonic/blog/540544/

Хотя нет, у тебя другое.


HPW-Dev
> Я уже пробовал снизить порог с 50 до 40 фпс или брать среднее значение времени
> 4-х и более фреймов
Сколько именно более? На 10 фреймах остаётся проблема? На 50?

Вообще, то, что один кадр отрисовался за 10мс,а второй за 23.3 (продали в swapbuffers vsync) может быть нормой, пока в среднем у тебя выходит 16.666 мс за фрейм. Но 4 кадра должны были сгладить эту проблему. Попробуй, для её диагностики, включить тройную буфыеризацию в драйверах (у тебя Opengl, поэтому в драйверах, на нормальных апи это можно сделать и в клиентской коде).

#2
21:43, 22 июля 2021

HolyDel
Возможно проблема как раз в том, что надо мерить время кадра на экране как написано в статье, но это только в вулкан апи, а моя видяха ещё и не поддерживает его.
Снижал до 40 фпс и сглаживание повышал до 30 кадров, но всё равно проскакивало иногда высокое значение задержки фрейма. Если возьму все 60 кадров, то адаптивное упрощение будет не эффективным, получится что одну секунду игра поработает быстро, а другую медленно - она выключит ускорение ведь эту секунду она рендерила с высоким фпс. Возможно надо придумать новую стратегию игнорирования статтеринга. Я попробую тройной буффер

#3
22:26, 22 июля 2021

HPW-Dev
> Снижал до 40 фпс и сглаживание повышал до 30 кадров, но всё равно проскакивало иногда высокое значение задержки фрейма.
Такое не получится списать на неравномерность каждого конкретного кадра.
У тебя случайно не происходят какие-нибудь тяжёлые штуки, типа погрузки текстур или чего то в этом роде? Не может быть такого, что у тебя за первые 0.5 секунды рисуется 10 кадров и за вторые 0.5 - 2000, когда текстура догрузилась? В сумме получается 2010 кадров в секунду, но если мерить время кадра, то получается печально.

HPW-Dev
> но это только в вулкан апи, а моя видяха ещё и не поддерживает его.
Более того, этот VK_GOOGLE_display_timing только андроидом поддерживается (вроде).

Не смотрел на свое приложение в цпу/ГПУ профайлерах?

#4
22:58, 22 июля 2021

HolyDel
Потом покажу лог со всей кардиограммой просадок. Графика рендерится на текстуру процессором, но она пиксельная и малого разрешения, потом всё свапается и выводится на экран. Именно при высоких выдаваемых фпс более 400 с включённой синхронизацией получаются такие приколы

#5
(Правка: 23:28) 23:28, 22 июля 2021

HolyDel
Похоже это действительно статтеринг и кадр может рисоваться по 30мс, таких пиков по 10 на 60 кадров и чем меньше нагружена сцена, тем они чаще
microfryze | Откуда берутся микрофризы и как с ними бороться?

#6
1:23, 23 июля 2021

Если программа (любая) создает и удаляет ресурсы на GPU что вызывает подкачку (пейджинг), то на время этой операции ВСЯ работа видеокарты замирает. Это связано с тем, что происходит перераспределение ресурсов в памяти карты и на время этого любая работа GPU блокируется. Это можно увидеть на GPUview. Бороться с этим нельзя, поскольку пейджинг может вызывать сторонняя программа.

#7
(Правка: 2:07) 2:04, 23 июля 2021

HPW-Dev
> и чем меньше нагружена сцена, тем они чаще

ну так нагрузка в игре должна быть равномерной.
Если сцена нагружена меньше чем надо то нужно догрузить её самому до уровня стабильных 60FPS.

#8
(Правка: 8:26) 7:59, 23 июля 2021

HPW-Dev
Так-то да, типичные статтерные пики - сначала пусто, потом густо.
Вот эти пики на #5, они уже со сглаживанием?
То, что у тебя один кадр занял 30мс, значит, что второй, рядом с ним занял 3.33, и в среднем они все равно должны были занять по 16.666.

#9
11:12, 23 июля 2021

Тоже боролся со статтерингом в своей игре (win версия тоже использует glfw), перепробовал кучу всего и забил. Минимизировать статтеринг получалось при:
1. уменьшении dip-ов за счет запекания всего и вся в атласы;
2. При фиксации дельта тайм через накопление его из плавающего dt в аккумулятор и скармливание аккумулятора update логике с фиксированным значением fdt = 1/120.0

#10
16:47, 23 июля 2021

san
Если текстура выделена в видеокарте и обновляется её битмап каждый фрейм, вызывает ли это освобождение/выделение ресурсов?

#11
(Правка: 17:09) 16:58, 23 июля 2021

Vitorio
Вот так делается накопление dt?

const frame_dt = 1/120.0
while ( !gamaover):
  sum_dt += dt
  while (sum_dt >= frame_dt):
    update(frame_dt)
    sum_dt -= frame_dt 
  dt = prev_time - cur_time
  prev_time = cur_time
#12
(Правка: 17:05) 17:03, 23 июля 2021

HPW-Dev
If на while замени. За один фрейм надо съесть всю накопленную дельту. Получится так, что update может быть вызван несколько раз за фрейм - это следствие перехода на фиксированный дельта тайм. Но в этом нет ничего страшного если update не тяжелый.

#13
17:11, 23 июля 2021

Vitorio
Да, заменил

#14
17:21, 23 июля 2021

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

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

Тема закрыта.