Quick Reference
| 병목 | 늘어나는 조건 |
|---|---|
| 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 |
측정 순서:
frame time -> CPU/GPU time 분리 -> 해상도·draw·geometry·texture·pass를 하나씩 바꿔 가설 검증구조
GPU 성능을 볼 때 “shader가 무겁다” 하나로 묶으면 원인을 놓치기 쉽습니다. 병목은 데이터를 보내는 CPU 쪽, 정점을 처리하는 단계, 화면 샘플을 처리하는 단계, 메모리 대역폭, 동기화 지점 중 어디서든 생길 수 있습니다.
CPU prepares commands
-> GPU vertex work
-> raster/fragment work
-> memory read/write
-> presentation정확한 진단은 profiler와 GPU capture가 필요하지만, 입력을 바꿔보는 것만으로도 축을 좁힐 수 있습니다. 해상도를 낮췄을 때 빨라지면 fragment/bandwidth 쪽일 가능성이 크고, 정점 수를 줄였을 때 빨라지면 vertex 쪽일 가능성이 큽니다.
이 실험은 단서이지 증명은 아닙니다. 해상도를 낮추면 fragment shading, render target bandwidth, post-process가 함께 줄고, draw를 합치면 CPU submission뿐 아니라 state change도 달라집니다. profiler에서 CPU frame time, GPU queue time, pass별 duration을 같은 frame capture로 보고 다음 실험을 정합니다.
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를 줄여도 효과가 작습니다.
sync bound는 평균 GPU utilization만으로 찾기 어렵습니다. CPU가 fence, present, resource map/readback에서 기다리거나 GPU가 queue dependency를 기다리는 구간을 timeline에서 확인합니다. readback을 frame마다 동기 호출하는 코드, 과도한 barrier, swapchain pacing이 원인이면 shader를 바꿔도 frame time이 줄지 않습니다.
주의할 점
평균 FPS만 보면 병목을 놓칠 수 있습니다. frame time, percentile, GPU time, CPU time을 분리해서 봐야 합니다.
또 최적화는 품질과 비용의 교환입니다. 텍스처, 그림자, 후처리, 조명 수를 줄일 때는 어떤 시각 품질을 포기하는지 명확히 해야 합니다.
한 번의 평균 FPS 대신 frame time percentile과 worst-frame capture도 남깁니다. shader compilation, streaming, garbage collection, first-use pipeline creation처럼 지속 병목이 아닌 spike는 원인과 대응이 다르므로 같은 숫자로 합치지 않습니다.
참고 링크
1 sources