캐시 친화적 데이터 구조
Data Oriented Design으로 CPU 캐시 효율을 극대화합니다
Data Oriented Design (DOD)
왜 데이터 배치가 중요한가
Data Oriented Design은 코드 병렬화, SIMD 연산 벡터화, 캐시 효율성을 통해 상당한 성능 향상을 가져옵니다.
CPU가 메모리에서 데이터를 가져올 때, 필요한 데이터 주변도 함께 캐시에 로드합니다. 연속된 메모리에 관련 데이터가 있으면 캐시 히트율이 높아집니다.
메모리 접근 속도 비교
Main Memory는 L1 Cache보다 100배 느림!
AoS vs SoA
데이터 레이아웃 비교
Position만 필요해도
전체 구조체 로드
캐시 낭비!
필요한 데이터만
연속 메모리 접근
캐시 히트!
Array of Structures (AoS) - 전통적 방식
// 전통적인 객체 지향 방식
struct Robot {
FVector Position; // 12 bytes
FVector Velocity; // 12 bytes
float Health; // 4 bytes
float Shield; // 4 bytes
FString Name; // 많은 bytes
};
TArray<Robot> Robots; // 메모리: [R0][R1][R2][R3]...
// Position만 업데이트할 때도 전체 구조체가 캐시에 로드됨
for (Robot& R : Robots)
{
R.Position += R.Velocity; // Name 등 불필요한 데이터도 캐시 점유
}
Structure of Arrays (SoA) - 캐시 효율적
// 데이터 지향 방식
struct RobotData {
TArray<FVector> Positions; // [P0, P1, P2, P3, ...]
TArray<FVector> Velocities; // [V0, V1, V2, V3, ...]
TArray<float> Healths; // [H0, H1, H2, H3, ...]
TArray<float> Shields; // [S0, S1, S2, S3, ...]
TArray<FString> Names; // [N0, N1, N2, N3, ...]
};
RobotData Data;
// Position 업데이트: 연속된 메모리 접근
for (int32 i = 0; i < Data.Positions.Num(); ++i)
{
Data.Positions[i] += Data.Velocities[i]; // 캐시 히트 극대화!
}
성능 비교 (Unreal Insights 측정)
SoA는 AoS보다 6배 빠름!
실전 적용
언제, 어떻게 SoA를 적용할까
SoA 적용이 효과적인 경우
대량의 동일 오브젝트
수백~수천 개의 파티클, 총알, NPC 등
부분 속성만 업데이트
Position만, 또는 Health만 자주 업데이트
단순 반복 연산
SIMD 벡터화가 가능한 수학 연산
struct ParticleSystemData
{
// Hot data - 매 프레임 접근
TArray<FVector> Positions;
TArray<FVector> Velocities;
TArray<float> LifeTimes;
// Cold data - 가끔 접근
TArray<FLinearColor> Colors;
TArray<float> Sizes;
void UpdatePositions(float DeltaTime)
{
// 연속 메모리 접근으로 캐시 효율 극대화
const int32 Count = Positions.Num();
for (int32 i = 0; i < Count; ++i)
{
Positions[i] += Velocities[i] * DeltaTime;
LifeTimes[i] -= DeltaTime;
}
}
};
Mass Entity (ECS)
UE5의 데이터 지향 프레임워크
Mass는 UE5의 Entity Component System(ECS) 모듈로, CPU 메모리 캐싱 아키텍처에 최적화된 데이터 저장 방식을 사용합니다.
📦 Fragment
데이터 컴포넌트
(Position, Velocity 등)
🔖 Entity
Fragment들의 조합 ID
(Actor 대체)
⚙️ Processor
Fragment를 처리하는 시스템
(로직 담당)
📁 Archetype
동일 Fragment 조합의
엔티티 그룹
Mass는 Experimental 상태이지만, 대량의 동일 오브젝트(군중, 파티클 등)를 처리할 때 기존 Actor 방식보다 훨씬 효율적입니다. Fortnite의 군중 시스템에 사용됩니다.
핵심 요약
- Data Oriented Design: 데이터 배치를 CPU 캐시에 최적화
- AoS (Array of Structures): 전통적 방식, 캐시 비효율적
- SoA (Structure of Arrays): 캐시 효율적, 최대 6배 성능 향상
- 적용 대상: 대량 동일 오브젝트, 부분 속성 업데이트, 단순 반복 연산
- Mass Entity: UE5의 ECS 프레임워크 (Experimental)
CPU 최적화를 마스터했습니다! 다음 Part에서는 GPU 최적화의 핵심인 Draw Call 최적화, Shader Complexity, Nanite/Lumen/VSM 최적화를 다룹니다.
도전 과제
배운 내용을 직접 실습해보세요
TArray
기존 AoS(Array of Structures) 패턴의 파티클 시스템을 SoA(Structure of Arrays) 패턴으로 변환하세요. 위치, 속도, 수명을 별도 배열로 분리하여 캐시 히트율 향상을 확인합니다.
1000개 이상의 프로젝타일 업데이트 시스템을 Data-Oriented 방식으로 재설계하세요. ISPC 또는 수동 SIMD를 활용하여 위치 업데이트를 벡터화하고, 기존 OOP 방식 대비 성능 향상을 측정합니다.