데이터 지향 설계 소개
데이터 지향 설계 소개
데이터 지향 설계는 객체 계층보다 메모리 레이아웃을 우선시하여 성능을 극대화합니다
Data-Oriented Design (DOD)은 "객체"보다 메모리에서 데이터가 어떻게 읽히고 쓰이는가에 초점을 맞추는 소프트웨어 설계 접근법입니다. 데이터의 개념적 정체성보다 접근 패턴에 따라 데이터를 조직함으로써 개발자는 CPU 캐시 미스를 크게 줄이고 멀티스레딩 및 GPU·APU와 같은 하드웨어 오프로드 구현을 단순화할 수 있습니다.
성능 격차: 메모리 지연 vs. CPU 속도
현대 CPU 성능은 메모리 지연에 크게 병목됩니다. CPU는 몇 사이클 안에 명령을 실행할 수 있지만, 메인 메모리에서 데이터를 가져오는 데는 수백 사이클이 걸릴 수 있습니다.
- L1/L2 캐시: 1–2 사이클
- 메인 메모리: 최대 600 사이클 (3.2 GHz 기준)
데이터가 메모리 여기저기에 흩어져 있으면 CPU는 계산을 수행하기보다 데이터를 기다리는 데 대부분의 시간을 소비합니다. DOD는 특정 연산에 필요한 데이터가 메모리에서 연속적으로 저장되도록 하여 CPU에 지속적으로 데이터를 공급하는 것을 목표로 합니다.
객체 지향 설계 (OOD) vs. 데이터 지향 설계 (DOD)
OOD 문제: 캐시 미스와 사용되지 않는 데이터
객체 지향 설계에서는 데이터가 일반적으로 클래스에 묶입니다. 예를 들어 Bot 클래스는 위치, 수정자, 목표 방향 등을 포함할 수 있습니다. 프로그램이 1,000개의 봇에 대해 목표 방향을 업데이트할 때 각 봇마다 전체 Bot 객체를 캐시로 로드합니다.
이로 인해 두 가지 주요 비효율이 발생합니다:
- 데이터 미스: 현재 연산에 필요하지 않은 데이터(예:
Bot의 이름이나 인벤토리)를 포함한 전체 객체를 CPU가 로드합니다. - 명령 캐시 미스: 여러 객체에 대해
updateAim()같은 메서드를 호출하면 코드 실행이 자주 점프하게 되어 iCache 미스가 발생합니다.
DOD 해결책: 선형 배열과 변환
DOD는 시스템을 일련의 변환으로 취급합니다: Data In → Transform → Data Out. Bot 객체 대신 DOD는 속성을 별개의 선형 배열(구조체 배열이 아닌 배열 구조)로 저장합니다.
예시: Bot 목표 업데이트
- OOD 접근법:
Bot객체 배열을 순회하면서bot.updateAim()을 호출합니다. - DOD 접근법:
positions선형 배열,modifiers선형 배열, 목표 위치를 함수에 전달합니다. 함수는 이 배열들을 선형으로 순회하면서 결과를aimDirections선형 배열에 기록합니다.
이렇게 하면 CPU 캐시 라인(보통 128 바이트)으로 로드되는 모든 바이트가 현재 계산에 사용되어 메모리 대역폭 낭비와 지연을 없앨 수 있습니다.
핵심 구현 원칙
"뒤에서 앞으로" 설계
개발자는 먼저 필요한 출력 데이터를 정의하고, 그 출력을 만들기 위해 최소한의 입력 데이터만을 결정해야 합니다. 이렇게 하면 성능에 중요한 경로에 불필요한 데이터가 포함되는 것을 방지할 수 있습니다.
네이티브 데이터 vs. 소스 데이터
데이터는 실행되는 하드웨어에 맞게 미리 포맷되어야 합니다. 예를 들어 소스 데이터는 편집을 위해 연결 리스트 형태로 저장될 수 있지만, 런타임에 사용되는 네이티브 데이터는 캐시 효율성을 위해 연속 배열로 변환되어야 합니다.
병렬성 및 하드웨어 오프로드
DOD는 데이터와 코드를 분리하고 선형으로 조직하기 때문에 병렬화가 훨씬 쉬워집니다. 데이터가 명확히 정의되고 격리되어 있으면 복잡한 락 없이도 GPU·SPU와 같은 공동 유닛으로 오프로드할 수 있으며, 데이터 접근 패턴이 예측 가능하고 자체적으로 포함됩니다.
비판적 관점과 트레이드오프
DOD가 엄청난 성능 향상을 제공하지만, 특정 아키텍처적 도전을 동반합니다:
- 유연성 vs. 성능: 일부 실무자는 요구 사항이 자주 변할 경우 DOD가 OOD보다 유연성이 떨어진다고 주장합니다. 데이터 레이아웃이 특정 알고리즘에 밀접하게 결합되어 있기 때문에 "문제"가 바뀌면 데이터 구조를 완전히 재설계해야 할 수도 있습니다.
- 적용 범위: DOD는 물리 엔진, 3D 렌더러, 게임 엔진 등 대량의 데이터를 병렬 처리하는 시스템에서 가장 효과적입니다. 작은 데이터셋에서는 별도 배열을 관리하는 오버헤드가 성능 이점을 상쇄할 수 있습니다.
- ECS와의 관계: Entity Component Systems (ECS)는 DOD를 구현하기 위한 프레임워크로 자주 사용됩니다. 모든 문제에 완벽한 해결책은 아니지만, ECS는 깊은 OOD 계층보다 근접 최적 성능을 달성하는 데 더 유연한 편입니다.
"다른 데이터를 가지고 있다면, 다른 문제가 있다." — Mike Acton 접근법에 대한 논의에서 종합된 통찰
SUMMARY: Data-Oriented Design (DOD) prioritizes memory layout and data access patterns over object hierarchies to maximize CPU cache efficiency and enable massive parallelism.
TITLE: Introduction to Data-Oriented Design