Optimalizace výkonu
Optimalizace výkonu herních aplikací je disciplína na pomezí programování, grafiky, datového inženýrství a designu. Cílem je udržet stabilní dobu snímku v definovaném rozpočtu (např. 16,67 ms pro 60 FPS, 8,33 ms pro 120 FPS, 11,11 ms pro VR 90 Hz) při co nejvyšší vizuální kvalitě a škálovatelnosti napříč platformami. Tento článek shrnuje metodiku profilování, klíčová úzká hrdla (CPU, GPU, paměť, I/O), optimalizační vzory a specifika jednotlivých platforem (PC, konzole, mobilní zařízení, VR).
Metodika: měř, izoluj, iteruj
- Definuj cílové FPS a rozpočet snímku: stanov dílčí rozpočty (renderování, fyzika, AI, skripty, síť, I/O) a sleduj je v CI.
- Profiluj cíleně: nejprve na vysoké úrovni (doba snímku CPU/GPU, špičky/záseky), poté proveď podrobnější analýzu (draw cally, chybějící zásahy do cache, typy prodlev).
- Reprodukuj špičku: používej deterministické záznamy (záznam replaye), uzamkni hodnoty seedů a zachovej stejné trasy kamery.
- Optimalizuj podle dat: vyhýbej se mikrooptimalizacím bez dopadu na rozpočet snímku.
Nástroje pro profilování a inspekci
- CPU: VTune, Tracy, Perfetto, Unreal Insights, Unity Profiler/Deep Profiler, Xcode Instruments, Windows Performance Analyzer.
- GPU: RenderDoc (graf snímků, overdraw), NVIDIA Nsight Graphics/Systems, AMD Radeon GPU Profiler/RGA, PIX for Windows/Xbox, Xcode GPU Frame Capture.
- Paměť a I/O: nástroje platformy pro sledování haldy, AddressSanitizer, Unreal MemReport, Unity Memory Profiler, záznam I/O operačního systému.
- Síť: Wireshark, netstat/ss, nástroje enginu pro profilování replikace.
Diagnostika: omezení CPU vs. omezení GPU
- Omezení CPU: vysoká doba snímku CPU (game thread/render thread), nízké využití GPU. Příčiny: vysoký počet draw callů, AI, skripty, fyzika, alokace, synchronizace.
- Omezení GPU: doba snímku GPU > cílový rozpočet, CPU čeká (Present/Flush). Příčiny: fill rate/overdraw, náročné shadery, postprocesing, stíny, MSAA, vysoké rozlišení.
- Záseky: krátké špičky způsobené I/O, kompilací shaderů, GC, vytvářením PSO, streamováním assetů.
Renderovací pipeline a rozpočty
| Úloha | Cíl 60 FPS | Cíl 120 FPS | Poznámky |
|---|---|---|---|
| Geometrie (viditelnost, ořezávání) | 2–4 ms | 1–2 ms | Ořezávání podle frusta/zakrytí, LOD, instancování |
| Stíny + světla | 2–3 ms | 1–1,5 ms | Stínové mapy, dlaždicové/skupinové osvětlení |
| G-Buffer/Forward pass | 3–5 ms | 1,5–3 ms | Minimalizuj overdraw, optimalizuj shadery |
| Postprocesing | 1–2 ms | 0,5–1 ms | Bloom, TAA, DOF, SSR s rozumným nastavením |
| UI/HUD | 0,3–0,7 ms | 0,2–0,5 ms | Dávkové vykreslování, omezení průhlednosti |
Geometrie: ořezávání, LOD a draw cally
- Instancování a dávkové vykreslování: slučuj objekty se stejnými materiály/sítěmi; sniž počet draw callů a změn stavů.
- Level of Detail (LOD): generuj automaticky (zjednodušování sítě) a ručně pro klíčové modely; přepínej podle velikosti v obraze, ne podle vzdálenosti.
- Ořezávání podle zakrytí: kombinuj hi-z occlusion, portály v interiérech a předpočítanou viditelnost pro statické scény.
- Vykreslování zepředu dozadu: zlepšuje early-z; minimalizuj alfa test/průhlednost (dražší overdraw).
Shadery a materiály
- Omez větvení: upřednostňuj varianty/makra/konstanty specializace před dynamickým if v kritické části kódu.
- Textury: používej mipmapy, kompresi (BC/ASTC/ETC) a správné filtry; kontroluj anizotropii.
- Předehřátí PSO/shaderů: předkompiluj a ukládej do mezipaměti stavy pipeline; vyhni se kompilaci během hraní (zásekům).
- Postprocesing: slučuj průchody, vykresluj v nižším rozlišení (čtvrtinovém/polovičním) pro DOF/SSR/Bloom.
Návrh orientovaný na data (DOD) a ECS
- Efektivní využití cache: přeuspořádej data do struktur polí (SoA) pro sekvenční přístup; minimalizuj přeskakování mezi ukazateli.
- Entity Component System (ECS): zpracovávej komponenty v hustých blocích, používej iterace vhodné pro úlohy bez virtuálních volání.
- Alokace: vlastní alokátory, frame/arena/pool; vyhýbej se alokacím v horkých smyčkách.
Multithreading a systémy úloh
- Graf úloh: rozděl práci na malé úseky (0,1–0,5 ms), deklaruj závislosti a využij všechna jádra.
- Render thread vs. game thread: minimalizuj synchronizační bariéry; používej dvojité/trojité bufferování datových struktur.
- Asynchronní výpočty: přesouvej výpočty (částice, ořezávání podle zakrytí, postprocesní efekty) do asynchronních front, pokud to GPU a API umožňují.
Fyzika, animace a AI
- Fyzika: široká fáze (BVH/Uniform Grid) je klíčová; omez rigidbody u dekorací, používej uspávání a dílčí kroky jen u kritických interakcí.
- Animace: komprimuj klíčové snímky, používej skinning na GPU a LOD animací (méně kostí, nižší frekvence aktualizací mimo obraz).
- AI: omez frekvenci tiků a rozpočet uvažování, používej LOD chování, dávkové zpracování hledání cest a ukládání dotazů na navmesh do mezipaměti.
Paměť, GC a fragmentace
- Rozložení: odděluj objekty s dlouhou a krátkou životností; používej arény pro jednotlivé subsystémy, aby se snížila fragmentace.
- GC (spravované enginy): vyhýbej se alokacím v Update/Render; používej structs/pools, Span/NativeArray, explicitní GC pouze v bezpečných okamžicích.
- Diagnostika: sleduj špičky využití haldy, nástroje pro kontrolu úniků paměti a rozdíly mezi snímky stavu; omez velikost textur/sítí podle cílové platformy.
Asset pipeline a streamování
- Kompresní formáty: textury (BC/ASTC/ETC), sítě (meshopt/Draco), zvuk (ADPCM/Opus podle platformy).
- Streamování mipmap: streamuj podle vzdálenosti/velikosti v obraze; přednačítej mipmapy pro objekty LOD0 blízko kamery.
- Optimalizace I/O: upřednostňuj velká sekvenční čtení před malými náhodnými; zarovnávej bloky na hranice stránek; asynchronně dekomprimuj na vlákně úloh.
Řízení rozlišení a kvality
- Dynamic Resolution Scaling (DRS): měň měřítko render targetu podle vytížení GPU a zachovej stabilní dobu snímku.
- Upscalery: TAAU/FSR/DLSS/XESS – vyvažuj kvalitu a výkon, dbej na stabilitu pohybu (řízení jitteru).
- Úrovně škálovatelnosti: předem definuj profily (Low/Medium/High/Ultra) s jasným dopadem na rozpočet.
Tempo snímků a synchronizace
- VSync a bufferování: dvojité/trojité bufferování, minimalizuj čekání na present; upřednostňuj režimy s nízkou latencí, pokud je rozpočet stabilní.
- Pevné časové kroky: herní logiku zpracovávej v pevném taktu (např. 60 Hz), vykresluj s proměnlivou frekvencí; pro plynulý obraz extrapoluj/interpoluj.
- Odhalení příčiny záseků: kompilace PSO, disková mezipaměť shaderů, streamování – používej zahřívací obrazovky a přednačítej kritické zdroje.
UI a overdraw
- Dávkové vykreslování UI: slučuj části vykreslování, minimalizuj změny materiálu/písma; používej atlasovaná písma a sprite sheets.
- Průhlednost: vykresluj UI jako poslední, vyhýbej se celoplošným průhledným vrstvám; ořezávej obsah mimo obraz.
Multiplayer: náklady na síť a replikaci
- Tickrate: optimalizuj serverový takt 30–60 Hz podle žánru; interpolace/extrapolace na klientovi minimalizuje jitter.
- Rozdílový přenos stavů a prioritizace: posílej změny, ne celé stavy; prioritizuj podle cíle (blízkost kamery, relevance).
- Kompromis mezi šířkou pásma a CPU: komprese a agregace paketů versus náklady na CPU; zpracování v pipeline systému úloh mimo hlavní vlákno.
Specifika VR a AR
- Rozpočet: 72–120 Hz (13,9–8,3 ms); vykreslování pro obě oči nebo single-pass instancing.
- Timewarp/Spacewarp: stabilizuj latenci, vyhýbej se zásekům; predikce pohybu hlavy je citlivá na jitter.
- Foveované vykreslování: pevné/sledování pohybu očí; šetří fill rate u mobilních headsetů.
Mobilní platformy
- Tepelné limity: plánuj rozpočty pro dlouhodobě udržitelný výkon, nejen pro krátkodobý; sleduj thermal throttling.
- Dlaždicové odložené renderery: minimalizuj zbytečné změny render targetů, využívej optimalizace discard/load/store.
- Paměť: agresivně komprimuj textury (ASTC), minimalizuj počet variant shaderů a používej menší render targety (HDR jen tam, kde je nutné).
Konzole a PC
- Mezipaměť PSO: sestavuj a distribuuj databázi PSO; zakaž kompilaci za běhu.
- Asynchronní I/O: nové generace (NVMe + DMA) – připrav streamovací rozhraní s velkými bloky a grafem závislostí.
- Variabilita PC: benchmarkové profily, automatický výběr kvality, robustní heuristika DRS a omezení počtu vláken CPU.
Průběžné výkonnostní testy
- CI výkonu: automatické boty spouštějí definované trasy kamer a porovnávají doby snímků, draw cally, VRAM/RAM CPU a počet záseků.
- Práh regrese: PR nesmí zhoršit metriky nad stanovenou toleranci; ukládej profily snímků pro porovnání.
- Telemetrie v terénu: anonymní RUM: percentily FPS, teploty, kombinace hardwaru; škáluj podle skutečných podmínek.
Kontrolní seznam rychlých zlepšení
- Sniž počet materiálů a draw callů (instancování, atlasy).
- Zapni mipmapy a správné filtrování, oprav mip streaming holes.
- Zakaž kompilaci shaderů za běhu; předehřívej PSO během načítání.
- Optimalizuj průhledné vrstvy a postprocesing (poloviční rozlišení, slučování průchodů).
- Přesuň náročné subsystémy do úloh (částice, ořezávání podle zakrytí, ořezávání).
- Uprav vzdálenosti LOD podle velikosti v obraze, ne podle lineární vzdálenosti.
- Zabraň alokacím v cestě vykreslování snímku; používej pooly a arény.
- Zaveď DRS a moderní upscaler pro stabilní tempo snímků.
Tabulka: běžné příznaky a náprava
| Příznak | Pravděpodobná příčina | Doporučený postup |
|---|---|---|
| Doba snímku GPU > rozpočet v interiérech | Příliš velký overdraw, náročné postprocesní efekty | Optimalizuj průhledné materiály, použij postprocesní efekty v polovičním rozlišení, depth pre-pass |
| Špičky CPU při pohybu | Streamování assetů, alokace, PSO | Přednačítání, mezipaměť PSO, alokace v aréně, dávkové asynchronní I/O |
| Kolísání FPS při větším počtu NPC | Takt AI bez stanoveného rozpočtu, nárazové hledání cest | LOD AI, rozpočet taktu, dávkové dotazy na hledání cest, mezipaměť navmesh |
| Rozmazaný obraz při použití upscaleru | Nesprávný jitter, nevhodné doostření | Stabilizuj TAA, použij správné vektory pohybu, jemné doostření |
| Nevolnost ve VR | Jitter/záseky, vysoká latence | Uzamkni snímkovou frekvenci, upřednostňuj stabilitu, agresivní DRS, přednačítání zdrojů |
Postup optimalizace krok za krokem
- Stanov cílové FPS a rozpočty jednotlivých subsystémů.
- Sestav deterministický test (replay) a výchozí metriky.
- Identifikuj největší úzké hrdlo (CPU/GPU) a jeho příčinu.
- Proveď změnu s největším dopadem a nejnižšími náklady a změř rozdíl.
- Zajisti, aby se dosažené zlepšení zachovalo (výkonnostní test v CI), a pokračuj k dalšímu úzkému hrdlu.
- Pravidelně kontroluj varianty shaderů, LOD, rozpočty assetů a mezipaměť PSO.
Shrnutí
Výkon her není jednorázový cíl, ale průběžný proces řízený daty. Kombinací disciplinovaného profilování, návrhu orientovaného na data, rozumného využití GPU (ořezávání, LOD, shadery, PSO), stabilního tempa snímků a robustního streamování assetů lze dosáhnout plynulého chodu napříč hardwarem. Začleněním výkonnostních testů do CI a stanovením jasných rozpočtů pro každý subsystém udržíte výkon pod kontrolou po celou dobu vývoje i po vydání.
