유니티/개념

[Unity DOTS] 5. Synergy (Performance Trinity)

tae-woong 2026. 1. 3. 02:47
0. 서론

삼위일

지금까지 유니티의 새로운 기술 스택인 DOTS를 구성하는 세 가지 기둥을 하나씩 살펴보았다.

  1. [ECS] : 데이터를 메모리에 예쁘게 정렬하여 캐시 적중률(Cache Hit)을 높인다.
  2. [Job System] : 정렬된 데이터를 안전하게 나누어 멀티 코어(Multi-Core)로 병렬 처리한다.
  3. [Burst Compiler] : C# 코드를 SIMD 기계어로 변환하여 연산 속도를 극한으로 올린다.

각각의 기술도 훌륭하지만, DOTS의 진정한 가치는 이 셋이 만났을 때 발생하는 시너지(Synergy)에 있다.

 

 이 3요소가 어떻게 서로의 약점을 보완하고 강점을 극대화하여 'Performance Trinity'를 완성하는지 정리해 본다.

 

1. 데이터의 고속도로 주행 (The Data Flow)

우리가 작성한 코드가 CPU에서 실행될 때, 데이터는 다음과 같은 과정을 거친다.

 

과정에서 DOTS의 3요소가 어떻게 맞물리는지 살펴보자.

 

1단계 : ECS가 길을 닦는다 (Memory Layout)

  • 상황 : 5만 명의 군중 데이터를 처리해야 한다.
  • 역할 : ECS는 Archetype과 Chunk 시스템을 통해 데이터를 메모리의 연속된 공간(Linear Memory)에 차곡차곡 쌓아둔다.
  • 효과 : 데이터가 흩어져 있지 않으므로, CPU는 한 번 메모리에 접근할 때 필요한 데이터를 한가득 가져올 수 있다. (Cache Miss 최소화)

 

2단계 : Job System이 차선을 나눈다 (Parallelism)

  • 상황 : 길은 닦였는데, 운전자가 한 명(Main Thread)이면 처리가 늦다.
  • 역할 : IJobParallelFor는 ECS가 정렬해 둔 거대한 데이터 배열을 여러 개의 배치(Batch)로 쪼갠다. 그리고 미리 대기 중인 워커 스레드(Worker Threads)들에게 분배한다.
  • 효과 : 8코어 CPU라면 8명의 일꾼이 동시에 달려들어 데이터를 처리한다. (CPU 자원 100% 활용)

 

3단계 : Burst Compiler가 부스터를 켠다 (Vectorization)

  • 상황 : 일꾼들이 데이터를 가져갔지만, 계산 속도 자체는 C# 수준이다.
  • 역할 : Burst는 각 스레드가 수행하는 반복문(for)을 분석하여 SIMD(단일 명령 다중 데이터) 명령어로 바꿔버린다.
  • 효과 : 한 번의 CPU 사이클에 1개의 데이터가 아니라 4개, 8개의 데이터를 동시에 계산한다. (하드웨어 가속)

 

2. 왜 셋이 뭉쳐야 하는가? (The Necessity)

"그냥 Job System만 쓰면 안 되나요?" 혹은 "Burst만 켜면 안 되나요?"라는 질문이 생길 수 있다.

 

결론부터 말하면 가능은 하지만, 진정한 성능은 나오지 않는다.

 

시나리오 A : ECS 없는 Job + Burst

  • 상황 : MonoBehaviour 객체들의 데이터를 모아서 NativeArray로 복사한 뒤 Job을 돌린다.
  • 문제점 : 객체지향 방식(OOP)으로 흩어져 있는 데이터를 모으는(Copy) 과정 자체가 비용이다. 또한, 데이터를 다시 객체에 적용할 때도 병목이 생긴다. 즉, 배보다 배꼽이 더 커질 수 있다.

 

시나리오 B : Burst 없는 ECS + Job

  • 상황 : 데이터도 정렬됐고 병렬로 돌리지만, C# 일반 컴파일러(Mono/IL2CPP)를 사용한다.
  • 문제점 : 멀티 코어는 활용하지만, 코어 하나하나의 연산 속도는 평범하다. 특히 복잡한 수학 연산에서는 SIMD를 활용하는 Burst에 비해 수 배에서 수십 배 느리다.

 

시나리오 C : Job 없는 ECS + Burst

  • 상황 : 메모리는 깔끔하고 연산도 빠르지만, 메인 스레드 혼자 일한다.
  • 문제점 : 최신 CPU의 코어 15개는 놀고 있고, 1개만 죽어라 일한다. 대규모 물량을 처리하기엔 역부족이다.

 

결론 :  ECS가 데이터를 공급하고(Input), Job이 분배하며(Distribute), Burst가 처리(Execute)하는 이 구조는 서로가 서로의 전제 조건이 되어준다.

 

3. 성능의 증명 (The Proof)
(28분 ~ 48분)5만개 큐브 시뮬레이션

유니티 코리아가 제공한 '5만 개의 큐브' 예제는 이 시너지를 시각적으로 증명한다.

  1. 기존 방식 (GameObjects) : 2~3 FPS. 메인 스레드 과부하로 화면이 멈춘 수준.
  2. ECS + Job System : 60 FPS. 멀티 코어를 활용하여 부드러워졌으나, 연산량이 많아지면 한계가 옴.
  3. ECS + Job + Burst : 100 FPS 이상. SIMD 최적화까지 더해지자 CPU에 여유가 생기기 시작함.

단순히 "빠르다"를 넘어, 기존 방식으로는 불가능했던 규모(Scale)의 콘텐츠를 가능하게 만드는 것이 DOTS의 핵심이다.

 

4. 시리즈를 마치며 : DOTS가 여는 미래

글 정리를 통해, 객체 지향(OOP)에서 데이터 지향(DOD)으로의 패러다임 전환을 살펴보았다.

  • Why : 하드웨어의 발전 속도 차이(Memory Wall)를 극복하기 위해.
  • How : ECS로 메모리를 정리하고, Job System으로 작업을 병렬화하며, Burst로 연산을 최적화한다.

DOTS는 단순히 "프레임 좀 더 잘 나오는 기술"이 아니다.

 

수천 마리의 몬스터가 등장하는 MMORPG, 방대한 상호작용이 일어나는 오픈 월드, 복잡한 물리 시뮬레이션이 필요한 RTS 게임 등, 차세대 대규모 게임을 만들기 위한 필수적인 기반 기술이다.

 

시간이 나면, 유니티에서 제공해 주는 샘플 프로젝트도 한번 정리해 볼 생각이다.