[Graphics] Draw Call과 CPU, GPU 병목
Draw Call이란 무엇이며, 이를 줄이는 방법은?
GPU에 "어떻게 그려줘"라는 명령 한 번을 의미
오브젝트 하나를 그릴 때마다 GPU에 그리라고 요청 보내는데,
드로우 콜이 많을 수록 CPU -> GPU 전송 비용이 커져 성능 저하 발생
왜 드로우 콜이 많으면 느려지는가?
- CPU는 한 번에 하나씩 명령을 GPU에 보내야 함
- 드로우 콜이 많으면 CPU 병목, GPU가 기다리게 됨
- 모바일, 저사양 디바이스는 더 심각
드로우 콜 줄이는 방법
1. Batching 활용하기
| Static Batching | 움직이지 않는 오브젝트를 미리 묶음 |
| Dynamic Batching | 작은 오브젝트(버텍스 300개 이하)를 실시간으로 묶음 |
비슷한 메시, 머티리얼을 묶어서 한 번에 그리기 위해 사용
2. GPU 인스턴싱
- 같은 메시, 머티리얼을 반복해서 그릴 때 드로우 콜을 하나로 줄이는 기술
3. Sprite Atlas (Unity)
- 여러 스프라이트를 하나의 텍스처에 묶어주는 기능, 텍스처 변경 없이 여러 스프라이트를 렌더링 가능하여 드로우 콜 감소
4. UI 최적화
- 변경이 자주 일어나는 UI는 캔버스를 분리해서 리빌드 최소화
5. 머티리얼 공유
- 머티리얼이 다르면 드로우 콜 분리됨 -> 동일한 머티리얼을 여러 오브젝트에 재사용
6. 포스트 프로세싱 최소화
GPU와 CPU 간의 병목 현상을 줄이기 위한 방법?
CPU 병목: GPU는 한가한데 CPU가 너무 많은 작업을 하느라 GPU로 명령을 늦게 넘김
GPU 병목: CPU는 빠른데 GPU가 너무 많은 그리기 작업(셰이더, 텍스처, 파티클 등)을 하느라 프레임이 늦어짐
CPU 병목 줄이기
- 드로우 콜 줄이기, 불필요한 업데이트 제거, 오브젝트 풀링, 물리 최적화(콜라이더 줄이기, Fixed Update 최소화), 가비지 컬렉션 최소화, 멀티스레딩 활용
GPU 병목 줄이기
- 셰이더 최적화, 텍스처 해상도 줄이기, 조명 개수 줄이기, 포스트 프로세싱 줄이기, LOD
CPU -> GPU 병목 자체 줄이기
Command Buffer
- 렌더링 명령을 GPU에 미리 묶어서 넘겨주기
Async GPU Readback
- GPU 데이터를 읽을 때 비동기 방식 사용
Burst + Jobs + ECS (Unity)
- 대량의 연산을 GPU 친화적으로 병렬 처리 가능
Occlusion Culling
- 카메라에 보이지 않는 오브젝트 렌더링 제외