핵심 정리
| 병목 | 늘어나는 조건 |
|---|---|
| CPU submission | draw call, state change 증가 |
| Vertex bound | 정점 수, vertex shader 비용 증가 |
| Fragment bound | 화면 점유율, overdraw, fragment shader 비용 증가 |
| Texture bound | texture sample 수, cache miss 증가 |
| Bandwidth bound | 큰 render target, 많은 pass, G-buffer |
| Sync bound | CPU/GPU 대기, readback, resource hazard |
구조
GPU 성능을 볼 때 “shader가 무겁다” 하나로 묶으면 원인을 놓치기 쉽습니다. 병목은 데이터를 보내는 CPU 쪽, 정점을 처리하는 단계, 화면 샘플을 처리하는 단계, 메모리 대역폭, 동기화 지점 중 어디서든 생길 수 있습니다.
CPU prepares commands
-> GPU vertex work
-> raster/fragment work
-> memory read/write
-> presentation정확한 진단은 profiler와 GPU capture가 필요하지만, 입력을 바꿔보는 것만으로도 축을 좁힐 수 있습니다. 해상도를 낮췄을 때 빨라지면 fragment/bandwidth 쪽일 가능성이 크고, 정점 수를 줄였을 때 빨라지면 vertex 쪽일 가능성이 큽니다.
Overdraw
overdraw는 같은 화면 위치에 여러 fragment가 만들어지는 상황입니다. 불투명 물체는 depth test로 일부를 버릴 수 있지만, 투명 물체나 후처리 pass는 overdraw와 bandwidth 비용이 크게 나타납니다.
진단 기준
| 실험 | 빨라지면 의심 |
|---|---|
| 해상도를 낮춤 | fragment, bandwidth |
| 정점 수를 줄임 | vertex processing |
| 텍스처 해상도를 낮춤 | texture bandwidth, cache |
| draw call을 합침 | CPU submission |
| shader 분기를 줄임 | divergence, ALU |
| pass 수를 줄임 | bandwidth, render target switching |
성능 최적화는 가장 큰 병목부터 해야 합니다. vertex가 병목인데 fragment shader를 줄이면 체감이 없고, bandwidth가 병목인데 ALU를 줄여도 효과가 작습니다.
주의할 점
평균 FPS만 보면 병목을 놓칠 수 있습니다. frame time, percentile, GPU time, CPU time을 분리해서 봐야 합니다.
또 최적화는 품질과 비용의 교환입니다. 텍스처, 그림자, 후처리, 조명 수를 줄일 때는 어떤 시각 품질을 포기하는지 명확히 해야 합니다.
참고 링크
1 sources