Как подойти к регрессии в 30 FPS после добавления новой геймплейной системы?
После мерджа новой геймплейной системы (реактивная AI-толпа) сборка просела с 60 до 30 FPS. Вы запускаете stat unit до и после, затем снимаете трейс Unreal Insights (-trace=cpu,frame) и разворачиваете типичный кадр:
stat unit до: Frame 16.6 Game 8.2 Draw 4.1 GPU 9.0
stat unit после: Frame 33.3 Game 24.5 Draw 4.3 GPU 9.1
Трейс, дорожка игрового потока:
GameThread
└─ TickActors
└─ CrowdAgent::Tick 0.4 мс x 50 агентов = 20 мс
└─ FindPathSync синхронный поиск пути каждый кадр
Определите причину.
Профилируйте до и после через stat unit, чтобы увидеть, какой поток просел, затем снимите трейс Unreal Insights, чтобы найти стоимость новой системы. Делайте бисекцию: отключите систему, чтобы подтвердить причину, прежде чем оптимизировать.
- ✗Оптимизировать до замера того, какой поток на самом деле просел
- ✗Пропускать шаг бисекции, подтверждающий, что причина — новая система
- ✗Считать, что геймплейная система стоит только времени игрового потока, но не рендера
- →Как отличить регрессию потока рендера от регрессии игрового потока в трейсе?
- →Почему базовый замер до изменения критичен для этого подхода?
Сценарий
Команда добавила новую систему — например, реактивную AI-толпу. Сразу после мерджа сборка просела с 60 до 30 FPS. Нужно найти причину, а не гадать.
Диагностика
Шаг 1 — определите просевший поток. Запустите stat unit на ветке до и после изменения:
до: Frame 16.6 Game 8.2 Draw 4.1 GPU 9.0
после: Frame 33.3 Game 24.5 Draw 4.3 GPU 9.1
Game вырос с 8 до 24 мс — регрессия в игровом потоке, не в GPU. Понижать разрешение бессмысленно.
Шаг 2 — бисекция. Отключите новую систему (консольная переменная, флаг или удаление актора). Если FPS вернулся к 60 — причина подтверждена. Если нет — регрессия в другом месте, и трейс нужно читать иначе.
Шаг 3 — трейс. Снимите Unreal Insights с -trace=cpu,frame. Разверните типичный кадр на дорожке игрового потока и найдите блоки новой системы:
GameThread
└─ TickActors
└─ CrowdAgent::Tick ← 0.4 мс × 50 агентов = 20 мс
└─ FindPathSync ← синхронный поиск пути каждый кадр
Находка: каждый агент каждый кадр делает синхронный поиск пути.
Исправление
- Замените покадровый поиск пути асинхронными запросами и кэшируйте маршрут на несколько кадров.
- Поднимите
TickIntervalдля агентов или разнесите их обновления по кадрам (time-slicing). - Перепроверьте
stat unit—Gameдолжен вернуться к ~8 мс.
Оптимизируйте только после того, как замер указал точную причину.