..

엔진 프로그래머 임용식님의 강의

코드 최적화 및 그래픽스 프로그래밍

  • 프레임 기준 성능 목표
    • 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 순서 보장

마지막 요약

무조건 좋은 방법은 없음 → 상황에 따라 다름
프로파일링을 통해 현재 병목을 찾아야 함
정글 커리큘럼을 통해 최적화 방식에 대한 감각을 익혀야 함