본문 바로가기
Unity • C#

[Unity] DOTS: Jobs, Burst, ECS 간단 정리

by SAENS 2023. 6. 19.

이 글에서는 유니티의 데이터 지향 개발 기술에 대해서 설명 드리려 합니다.

먼저 제가 DOTS를 공부하는 데에 가장 도움이 많이 된 영상입니다: https://youtu.be/H7zAORa3Ux0

유니티 DOTS를 공부하고 싶으신 분들은 아래 정리 글을 보신 후 위 영상을 보시면 좋을 것 같습니다.

정리된 각 항목에 대해 깊게 파 보는 것도 좋지만, 얕게 알고 가는 것도 크게 상관은 없을 것 같습니다. 어차피 실제 돌아가는 코드를 봐야 이해가 제대로 됩니다.

# DOTS: 데이터 지향 기술 스택 #

  • DOTS는 데이터 지향 구현을 돕는 기술들을 지칭하는 용어
  • 데이터 지향 설계(DOD)를 통해 메모리 사용성 향상 → 성능 극적 향상
  • Unity의 DOTS: Job System, Burst Compiler, ECS

각각의 기술들이 독립적이기 때문에 셋을 반드시 함께 사용해야 할 필요는 없습니다. 즉, Jobs, Burst 없이 ECS를 사용할 수 있고, ECS 없이 Jobs, Burst를 사용할 수 있습니다. 그저 이 세 가지가 DOD 관점에서 궁합이 아주 좋기 때문에 다같이 사용하기를 권장하는 것입니다.

- Job System : 멀티스레딩

  • 여러 작업을 Job이라는 단위로 나눠 여러 스레드에 할당해주는 시스템.
  • 데이터 지향으로 설계되어 있는 경우에 Job을 스레드에 할당하는 작업이 더 원활하다고 함.
  • 성능 차이 알아보기: https://youtu.be/LuyfzLxOa88

- Burst Compiler: 코드 최적화

3차원 벡터 합 연산을 예로 들면, 각각의 성분에 대해 총 세 번의 합 연산을 하는 대신 단 한 번의 연산으로 처리(SIMD)할 수 있도록 하는 등의 최적화를 해줍니다.

- ECS: 아키텍처 프레임워크

  • ‘Entity’, ‘Component’, ‘System’ 세가지 요소들을 사용하는 데이터 지향 아키텍처.
    • ‘Entity Component’ system → 필자처럼 이렇게 끊어서 이해하시면 안됨
  • Unity의 ‘Entity 패키지’는 ECS 아키텍처를 통한 개발을 돕는 (코드 상의)인터페이스 및 에디터 환경을 제공.
  • 객체지향인 MonoBehaviour와 함께 사용 가능하기 때문에, 필요한 것만 ECS로 구현 가능.

ECS의 각 구성 요소와, 관련 중요 개념인 Aspect, Archetype은 다음과 같이 이해하시면 됩니다.

  • Component: 데이터. 그냥 데이터.
    • 데이터만 정의한 ScriptableObject와 비슷하지만, Component는 Entity에 종속됨.
  • Entity: Component의 집합
    • GameObject와 비슷하지만, 동작에 대한 정보는 가지지 않음.
  • System: 동작 구현 로직.
    • MonoBehaviour와 비슷하지만, System은 Entity에 종속되지 않음.
  • Aspect: 데이터 변환 로직. (선택사항)
    • 다수의 Component에 대한 종합적이고 세부적인 로직이 필요할 때 사용.
    • System에서는 여러 동작에 대한 로직, Aspect에서는 데이터 자체에 대한 세부적인 로직
  • Archetype: 같은 Component 구성을 가진 Entity를 모아서 분류한 단위.
    • 유니티가 알아서 분류해주니 크게 신경 쓸 필요 없음.

 

--- 기초적인 ECS Workflow

  1. SubScene에 GameObject 만들기
  2. GameObject는 자동으로 Entity로 변환됨
    • 에디터 모드에서 바로 확인 가능한 걸 보니 아마 컴파일 타임에 변환되는 듯 함.
    • 이 때 Transform, Collider 등 기본 Mono Component들이 ECS Component로 변환(Bake)되고, 관련 동작들은 System에 기본적으로 구현되어 있음.
  3. Component 스크립트(IComponentData 구조체) 생성
  4. 해당 Component에 대한 "Authoring" 스크립트(MonoBehaviour) 생성 및 Bake 메서드 정의
    • GameObject가 Authoring Mono Component를 가지고 있으면 Entity로 변환될 때 Bake 메서드가 호출됨.
  5. System 스크립트(ISystem 구조체 또는 SystemBase 클래스) 생성
    • 생성하면 어디에 따로 붙여주지 않아도 런타임에 알아서 작동함.
  6. System에서는 SystemAPI를 통해 특정 Component/Aspect/Archetype을 가진 Entity를 찾는 Query를 생성할 수 있음.
    • Aspect와 Archetype에 대한 Query는 내부적으로 1개 이상의 Component에 대한 Query와 같은 듯 함 - 뇌피셜)
    • 데이터에 대한 로직은 Component에 직접 접근하여 바로 작성할 수 있지만, 접근해야 할 Compoent가 2개 이상인 경우에 Aspect를 사용하는 것이 권장됨.
  7. Aspect 스크립트(IAspect 구조체) 생성, 데이터 관련 로직 정의
    • Aspect가 필드로써 참조하는 Component들을 가진 Entity는 에디터의 Inspector 창에서 해당 Aspect를 확인할 수 있음.

 

여기서 알 수 있듯이 기능 하나 구현하는 것도 아주 많이 복잡합니다. 그러니 너무 많은 데이터를 다루는 기능이 아니라면 그냥 기존에 하던 대로 구현하세요. 기존 Mono 클래스에서 SystemAPI 대신 EntityManager를 통해 쿼리를 수행하여 접근할 수 있고, 반대로 System 클래스에서 Mono 객체에 접근하는 것도 가능합니다. 객체지향과 데이터지향은 반대되는 개념이 아니라, 그냥 서로 다른 개념일 뿐입니다.

댓글