본문 바로가기

유니티/DOTS

[Unity] DOTS Overview

반응형

DOTS란 뭘까?

DOTS는 Data Oriented Technology Stack의 줄임말이다.

이는 DOP(Data Oriented Programming)와 비슷하다고 할 수 있다.

게임 엔진은 생산성을 위해 OOP(객체 지향 프로그래밍)으로 되어있는데, OOP가 장점만을 가지고 있는 것은 아니다.

이러한 OOP의 단점을 해결하고 DOP의 장점을 살려낸게 DOTS라고 할 수 있다.

 

DOTS는 사용하는 이유를 알기 위해 우리는 OOP의 장단점에 대해 먼저 알아야 한다.


OOP의 장점과 단점

장점

객체 지향 프로그래밍의 가장 큰 장점은 무엇보다 개발하기 편하다는 것에 있다.

프로그램 구조가 인간의 사고방식과 비슷하기 때문에 시스템을 구조화하기 편하다.

 

유니티를 예로 들면 하나의 사물/인물에 해당하는 단위는 게임오브젝트이다.

그리고 그 오브젝트의 기능을 담당하는 역할을 컴포넌트가 수행한다.

카메라의 컴포넌트들

예를 들어, 씬에 최소 하나 이상 존재하는 카메라는 카메라의 기능을 수행하기 위해 여러 스크립트로 이루어져 있다.

먼저 어떤 위치에서 어떤 방향으로 바라볼지에 대한 정보가 필요하므로 Transform을 갖고 있다.

또 카메라에 대한 정보(시야각, 컬링, Mask 등)가 필요하므로 Camera 컴포넌트도 필요하다.

그리고 보통 카메라가 유저가 되는 경우가 많기 때문에 Audio Listener 컴포넌트도 함께 붙는다.

 

여기서 우리가 알 수 있는 것은 빈 게임 오브젝트에 이름을 Main Camera라고 칭하고 필요한 기능을 컴포넌트(스크립트) 형태로 추가하였더니 카메라가 되었다는 것이다.

 

이렇게 유니티(혹은 언리얼)에서는 마치 레고를 조립하듯 객체를 조립하여 사용한다. 그리고 이러한 방식은 개발자로 하여금 빠른 개발 속도를 제공한다. 우리가 사고하는 방식 그대로 구현하면 되기 때문이다. (게임 오브젝트에 필요한 기능을 붙이면 될 뿐이다!)

LEGO

그리고 이러한 OOP의 구조가 복잡해져도 잘 컨트롤할 수 있게 해주는 역할이 상속, 다형성, 캡슐화, 정보은닉성 등이다.


단점

1. 설계의 복잡성

OOP의 구조가 복잡해질 경우 프로그래머는 상속, 다형성 등을 적극 활용해야 한다.

그러나 객체 지향 언어의 특성을 아무리 잘 활용하더라도 (우리는 사람이기 때문에) 결국에는 실수할 수밖에 없다.

문제는 객체 지향 언어에서의 잘못된 설계는 코드를 모두 갈아엎어야 하는 경우가 발생시킬 수 있다는 것이다.

 

예를 들어, A클래스에서 mesh라는 변수의 기능을 정의하고 A클래스를 상속받는 Aa클래스와 Ab클래스가 이를 override 하여 사용한다고 가정하자.

이러한 상태에서 개발 프로세스가 변경되어 mesh가 전혀 다른 역할을 하는 변수로 변경되었다면 Aa클래스와 Ab클래스는 심각한 버그를 발생시킬 수도 있는 상황이다.

이때 개발자는 모든 파생클래스(A를 상속받는 클래스)를 찾아내어 다 고쳐주어야 한다!

 

물론 위와 같은 상황이 발생하지 않도록 설계하는 것이 베스트이고 잘하는 개발자의 척도이겠지만 언젠가는 실수를 하기 마련이다. 따라서 문제가 발생할 때마다 해결할 수 있도록 작업 상황을 모두 기억하고 있어야 한다. 그리고 이는 분명한 OOP의 단점이다.

 

2. 높은 메모리 사용량

객체 지향 프로그래밍은 객체가 중심이지 않은가.

OOP는 객체를 기반으로 움직이기 때문에 많은 객체가 필요할수록 할당에 필요한 메모리도 늘어난다.

 

예를 들어, 방이 여러 개의 벽으로 이루어져 있다면 그 벽의 개수만큼 객체가 필요해진다.

유니티 하이라키

그리고 이는 메모리의 사용으로 이어진다. (왜냐면 객체(class)를 생성하려면 메모리가 필요하기 때문이다!)

사실 요즘의 디바이스는 충분한 메모리(여기서 메모리는 RAM을 의미)를 갖기 때문에 웬만한 게임에서 오브젝트의 생성은 거뜬하다. 그러나 그걸 뛰어넘는 아주아주 많은 객체가 필요할 경우 메모리 이슈는 충분히 문제가 될 수  있다.

 

객체가 많이 필요한 상황이 어떤 것이 있을까?

아마도 시뮬레이션 분야가 있을 것이다. 물리 시뮬레이션은 정교한 연산을 필요로 하기 때문에 수많은 물리 컴포넌트들(rigid body, collider, mesh 등)을 요구한다.

Physics

군중 시뮬레이션 게임 또한 마찬가지다. 수천 수만명 되는 캐릭터들이 모두 객체라면 메모리가 감당할 수 있을까?

Diplomacy is not an option 게임 (Unity엔진 사용)

 


풍부한 CPU에 비해 빈약한 RAM

다행히도 컴퓨터가 발전하며 메모리(RAM)의 성능은 점점 더 좋아졌지만 CPU는 그 보다 더 빠른 속도로 좋아졌다.

아래는 CPU와 메모리의 발전 속도를 비교한 표이다.

CPU-Memory gap

(출처: research gate)

 

문제는 OOP에서 수많은 객체들이 CPU 성능을 최대로 사용하였을 때 발생한다. 

CPU가 빠른 연산 속도로 일을 모두 처리해서 메모리에 전달하면 정작 메모리는 이전에 쌓인 결과물들을 처리하느라 정신이 없다.

이러한 현상을 메모리 병목현상이라고 하며 OOP에서 개발자가 해결해야 할 골칫거리이다.

 

만약 CPU가 일한 만큼 메모리가 일을 하지 않아도 된다면 우리는 CPU의 성능을 극대화해도 문제 될 것 없지 않을까?

DOTS는 이렇게 탄생하게 되었다.


언제 DOTS를 사용해야 할까?

위 예시 같은 경우, OOP를 사용하면 메모리 문제를 발생시키기 쉽다고 하였다.

그래서 많은 오브젝트가 필요한 게임은 DOP를 이미 사용하고 있다. 대표적인 예가 마인크래프트이다.

마인크래프트의 수만 개의 박스가 모두 객체라고 생각하면 끔찍하다. 그 많은 박스들이 각자 메모리를 차지한다. 하지만 DOP를 적용하여 아주 말끔하게 동작한다.

 

유니티는 물리 시뮬레이션이 가능하기 때문에 이를 DOTS와 함께 사용할 수 있도록 해두었다.

Havok

물리에 DOTS를 사용하면 복잡한 충돌체 처리도 빠르게 할 수 있다.

 

혹은 아주 많은 수의 차량 트래픽 관리나 군준 시뮬레이션 게임에도 적용할 수 있다.

 

이렇듯 DOTS는 메모리 문제가 발생할 수 있는 상황에서 사용해야 적합하다.

그 외의 상황에서는 굳이 DOTS를 사용할 필요가 없기 때문이다.

반응형