..
엔진 프로그래머 임용식님의 강의
코드 최적화 및 그래픽스 프로그래밍
- 프레임 기준 성능 목표
- 1초 / 60프레임 = 16.6ms: 프레임 하나당 처리 시간
- 캐시 친화적인 프로그래밍
- 공간적/시간적 지역성: 메모리 접근이 인접하거나 시간상 가깝다면 성능 증가
- 배열 기반 구조는 연속된 메모리 접근 → 캐시 히트율 증가
- 연결 리스트 대신 배열 리스트 사용 권장
- 구조체 내 배열 사용 (Structure of Arrays)
구조체 최적화
- 구조체 크기, 오프셋, 배열 내 구조 파악 → 파티클 시스템 최적화 예시
ECS 아키텍처 (Entity-Component-System)
- 기능 단위로 최소화된 객체 구성
- 매 프레임 갱신 시 캐시 히트 극대화
- 객체지향보다 데이터 지향 프로그래밍(DOP) 이 더 유리할 수 있음
메모리 재사용
- 객체 제거 대신 표시만 해서 재사용
- ex: alive flag
해시와 랜더링
- 해싱의 장점
- 객체를 해시값으로 변환 → O(1) 비교 가능
- 분류, 빠른 탐색에 유리
- GPU 렌더링 준비
- GPU 파이프라인 설정은 비용이 큰 작업
- 배치 렌더링: 동일 상태의 묶음을 한 번에 처리
부동소수점 연산
- GPU뿐만 아니라 CPU도 FP 연산 필수
- SIMD 장치: CPU 내 벡터화된 병렬 연산 장치
메모리 관리 전략
게임엔진의 특성
- 많은 리소스가 프레임마다 생성/삭제
- 대부분 작은 단위의 리소스
- 예측 가능한 메모리 사용, 복잡한 메모리 관리 필요
new/delete 문제점
- 메모리 단편화, 캐시 미스, 페이지 폴트
해결 전략
- 스택 할당자: 빠른 할당/해제
- 풀 할당자: 동일 크기 메모리 할당 → O(1) 속도
- 링크드 리스트로 청크 관리
- 작은 메모리 할당자: 소규모 할당이 많은 경우
OSTEP 및 OS 관련 개념
- 리소스 사용 최소화 → 관리 복잡도 ↓, 성능 ↑
- OS에서 Copy-on-write 전략 이해 필요
- 커스텀 메모리 할당자가 중요
PintOS 문제점 예시
- busy-wait는 CPU 낭비
- mutex는 효율적이나 시스템 콜 비용이 있음
락, 스레딩, Job 시스템
SpinLock
- CAS (Compare-And-Swap) 기반 원자적 연산
- 짧은 임계영역에는 적합하지만 CPU 자원 소모 위험
Lock-free 구조
- CAS 실패 비용이 커지면 오히려 성능 저하
- 스레드 경합 적을 때에만 효과적
Job 시스템
- 생산자-소비자 모델
- Worker Thread Pool + Job Queue
- Job은 구조적으로 나뉜 Task의 하위 단위
- Job Stealing: 유휴 worker가 다른 job을 도와줌
- Dependency Graph로 job 순서 보장
마지막 요약
무조건 좋은 방법은 없음 → 상황에 따라 다름
프로파일링을 통해 현재 병목을 찾아야 함
정글 커리큘럼을 통해 최적화 방식에 대한 감각을 익혀야 함