게임 그래픽스 최적화: CPU와 GPU 병목 구조
게임의 프레임 속도는 CPU와 GPU가 한 프레임을 함께 처리하며 결정된다. 두 장치 중 더 느린 쪽이 전체 속도를 제한하므로, 성능 문제를 해결하기 위해서는 병목 구간이 CPU인지 GPU인지 정확히 파악하는 것이 중요하다.
다음 내용은 CPU와 GPU에서 자주 발생하는 성능 저하 원인과 관리 방법을 정리한 것이다. 쉐이더 최적화 이전 단계에서 다뤄야 할 기본적인 요소들이다.
1. CPU 병목
CPU는 주로 애니메이션, 물리 계산, UI 갱신, 파티클 시스템 등 엔진 기능 처리에 부하를 받는다. 이 영역은 코드를 잘 짜는 것보다 데이터와 기능 사용이 효율적으로 구성되어 있는지가 더 중요하다.
1.1 애니메이션 데이터
애니메이션은 매 프레임마다 본(Bone) 단위로 커브를 샘플링하고 보간하며 동작한다. 본 수가 많을수록 CPU 연산량이 증가한다. 스키닝이 CPU에서 수행될 경우 부하가 더욱 커진다.
관리 지점
- 사용하지 않는 본과 키프레임 제거
- 블렌드 쉐입(Blend Shape) 키 수 최소화
- 고정된 변형은 미리 메시로 반영(bake)
- GPU 스키닝 사용 가능 시 CPU 스키닝 비활성화
Spine 2D처럼 CPU 스키닝만 지원하는 툴을 사용하는 경우, 애니메이션 개수와 병렬 실행 수를 제한하는 것이 필수적이다.
1.2 컨스트레인트와 애니메이션 시스템
유니티와 언리얼 엔진의 애니메이션 블루프린트나 컨스트레인트 시스템은 CPU 부하의 주요 원인 중 하나다. Late Update 단계에서 본 좌표를 갱신하거나, 여러 개의 컨스트레인트를 동시 처리하는 구조는 메인 스레드 사용량을 크게 높인다.
멀티스레딩을 지원하는 시스템도 존재하지만, 스레드 간 분산으로 인해 발열과 스로틀링이 발생할 수 있다. CPU의 전체 코어 점유율과 온도 변화까지 함께 모니터링해야 한다.
1.3 파티클 시스템
유니티의 내장 파티클 시스템은 기본적으로 CPU 기반으로 작동하며, 파티클 개수에 비례해 메인 스레드 부하가 증가한다. GPU 기반의 VFX Graph를 사용하는 것이 일반적으로 효율적이다.
주의 사항
- 대형 파티클은 픽셀 단위 연산이 많아 GPU에서도 부하 발생
- 파티클 크기와 중첩 수를 줄여 오버드로우(Overdraw) 방지
- CPU 파티클은 최소화하고, GPU 파티클로 전환
1.4 물리 연산(Physics)
물리 시스템은 멀티스레딩을 지원하더라도 충돌 검사와 트리거 처리는 여전히 메인 스레드에서 실행된다. 리지드바디와 콜라이더가 많을수록 CPU 부하가 급격히 증가한다.
개선 방법
- 불필요한 콜라이더 제거
- Static Collider 사용
- 단순 물리 효과는 GPU 컴퓨트 쉐이더 또는 VFX Graph로 이동
- Dots, Job System 등 병렬 물리 시스템 검토
테스트는 반드시 빌드 환경에서 진행해야 하며, 에디터 실행 결과만으로는 실제 성능을 판단하기 어렵다.
1.5 UI 렌더링
UI 시스템은 프레임당 계산량이 많다. 유니티의 자동 레이아웃(Horizontal/Vertical Layout Group)은 매 프레임 자식 오브젝트의 위치를 다시 계산하며, 캔버스(Canvas)는 자식이 하나라도 변경되면 전체를 리빌드한다.
최적화 방법
- 변경이 잦은 UI와 고정된 UI 분리
- 캔버스 단위 세분화
- 단순 HUD나 HP바는 3D 렌더링 패스로 전환
UI는 CPU가 드로콜(Draw Call)을 발행하는 구조이므로, 복잡한 레이아웃 구성은 CPU 부하로 직결된다.
2. GPU 병목
GPU는 병렬 처리를 기반으로 동작하지만, 구조적 제약으로 인해 특정 상황에서는 병목이 발생한다. 주된 원인은 오버드로우, 지나치게 작은 삼각형, 그리고 메모리 대역폭 압력이다.
2.1 오버드로우(Overdraw)
오버드로우는 하나의 픽셀이 여러 번 그려지는 현상이다. 반투명 오브젝트, UI 중첩, 대형 이펙트 등이 주 원인이다. GPU는 앞 픽셀이 완전히 처리될 때까지 다음 픽셀을 렌더링하지 못하므로 병렬 처리가 중단된다.
결과
- 병렬성 상실
- 메모리 접근 횟수 증가
- 캐시 효율 저하
디퍼드 렌더링(Deferred Rendering) 환경에서는 G-Buffer를 여러 장 사용하는 만큼 이 영향이 더 커진다.
대응 방법
- 투명 오브젝트 중첩 최소화
- UI 계층 단순화
- Quad Overdraw 모드로 모니터링
- 불필요한 효과 제거
2.2 작은 삼각형의 비효율
픽셀보다 작은 삼각형은 GPU에서 최소 2×2 픽셀 단위로 처리된다. 즉, 삼각형 하나가 작아도 4픽셀 단위의 연산이 발생한다. 작은 삼각형이 많으면 병렬 처리 효율이 급격히 낮아진다.
대표 사례
- 멀리서 보이는 고정밀 메시
- 세밀한 헤어, 옷 주름, 장식 오브젝트
개선 방법
- LOD(Level of Detail) 적용
- 거리에 따라 단순 메시로 교체
- 세밀한 표현은 노멀맵이나 디테일 텍스처로 대체
LOD의 핵심 목적은 버텍스 수를 줄이는 것이 아니라, 픽셀 단위 중복 계산을 감소시키는 것이다.
2.3 쉐이더 복잡도와 GPU 기능
GPU 스키닝, VFX 그래프, 복잡한 쉐이더, 텍스처 샘플링, 후처리 효과 등은 GPU 연산량을 크게 늘린다.
GPU는 병렬 연산이 강점이지만, 한 프레임 내에서 처리량이 과도해지면 전체 렌더링 속도가 급격히 떨어진다.
부하 요인
- 다중 드로콜(Draw Call)
- 복잡한 라이팅 계산
- 고해상도 텍스처 사용
- 중첩된 후처리(Post-processing)
프레임 디버거나 프로파일러를 사용해 병목이 픽셀 쉐이더, 버텍스 쉐이더, 메모리 전송 중 어느 단계에서 발생하는지 구체적으로 확인해야 한다.
3. 정리
최적화는 특정 기능을 추가하는 작업이 아니라, 시스템 전체를 효율적으로 유지하는 과정이다.
CPU와 GPU의 원리를 이해하지 못하면 하드웨어 성능이 아무리 좋아도 병목은 반복된다.
성능 향상은 기술적인 개선뿐 아니라, 데이터를 관리하고 병목 구조를 정확히 인식하는 것에서 시작된다.
하드웨어 성능이 높아질수록 더 많은 콘텐츠가 제작되기 때문에,
최적화의 중요성은 오히려 커지고 있다.
CPU와 GPU의 상호작용 구조를 이해하고, 데이터 흐름을 정리하는 것이 가장 현실적인 해결책이다.
'공부 일지 > 그래픽스' 카테고리의 다른 글
| GPU로 풀 그리기 #6 (完) (0) | 2025.10.14 |
|---|---|
| GPU로 풀 그리기 #5 (0) | 2025.10.14 |
| GPU로 풀 그리기 #4 (0) | 2025.10.11 |
| GPU로 풀 그리기 #3 (0) | 2025.10.05 |
| GPU로 풀 그리기 #2 (0) | 2025.10.05 |