EveryDay.DevUp

[Unity] DOTS - 프로세스, 스레드, C# Job 시스템 본문

Unity

[Unity] DOTS - 프로세스, 스레드, C# Job 시스템

EveryDay.DevUp 2020. 6. 3. 22:57

ECS를 알아보기 전 DOTS에 대해 궁금한 점이 있다면 하단의 링크를 통해 알아 볼 수 있다.

https://everyday-devup.tistory.com/67

 

[Unity] DOTS ( Data Oriented Technology Stack )

● DOTS란? ▶ Unity를 통해 멀티스레딩과 퍼포먼스 향상이 가능한 차세대 유니티 기반 기술이다. ▶ ECS, Job System, Burst Compiler 의 각 고유한 기능들을 사용하여 DOD ( Data-Oriented Design )을 구현 하..

everyday-devup.tistory.com

Unity의 Job System을 이해하기에 앞서 기본이 되는 프로세스, 스레드의 개념을 알아보고, Job 시스템이 무엇인지와 사용법을 설명하고자 한다.

● 프로세스

▶ 하드 디스크에 설치된 프로그램이 메인 메모리에 올라온 상태로, 백그라운드나 포그라운드에서 실행 중인 상태를 말한다.

( 예를 들어 단말기에 설치된 게임 런처를 실행하고, AFK Arena 게임을 실행하는 것이 모두 프로세스이다. )

[ 게임런처, AFK ARENA는 각기 하나의 프로세스 ]

▶ 프로그램이 실행되면 메인 메모리에 해당 프로그램의 코드, 리소스 데이터가 올라가고, 프로그램에서 사용할 메모리 ( 힙, 스택 )이 할당된다.

▶ 하나의 CPU에 다수의 프로세스가 실행될 수 있지만, 실제로 하나의 CPU가 한번에 처리할 수 있는 프로세스는 하나이다. 다수의 프로세스가 실행 중일 때에는 컨텍스트 스위칭을 통해 빠르게 프로세스가 전환된다. 사람이 인식하기에 그 순간이 너무 빠르기 때문에 동시에 여러개의 프로세스가 실행 중으로 보이는 것이다.

● 스레드

하나의 프로세스 안에서 둘 이상의 실행 흐름이 필요한 경우가 생길 수 있는데, 각 실행 흐름을 스레드라고 한다.

( 예를 들어 Unity에서는 메인 스레드와 렌더 스레드가 존재하는데 메인 스레드는 게임의 로직을 처리하고 렌더 스레드는 화면을 그리는 GPU의 처리를 담당한다. 만약 메인 스레드 하나만 존재하면 GPU에게 명령을 내리고 응답이 돌아올 때까지 게임 로직이 처리되지 않아 게임이 멈춘 것처럼 보일 것이다. )

[ Unity의 Main Thread/Render Thread ]

▶ 스레드는 프로세스에서 코드와 리소스, 힙 메모리 영역을 공유하고 스택 메모리 공간은 별도로 할당 된다.

▶ 스레드는 레이스 컨디션과 같은 문제가 생길 수 있다.

: 같은 메모리에 접근 하는 경우 스레드의 순서에 따라 의도치 않은 결과가 나올 수 있는 현상을 말한다.

: 다수의 스레드가 있을 때 순서에 따라 스레드가 수행되는 것이 아니기 때문에 스레드의 실행 시점에 따라 이슈가 발생할 수 있다.

[ 변수 A를 각 스레드에서 참조할 때 예상 결과는 103 ]
[ A 스레드의 결과가 나중에 반영되어 101이 나옴 ]

▶ CPU의 코어 개수가 늘어남에 한번에 처리할 수 있는 CPU 연산은 이론적으로는 많아졌지만, 실제로 게임에서는 코어를 2개 이상 사용하기 어렵다. 스레드가 병렬적으로 실행되고, 실행이 완료되면 결과를 동기화 해야되는 문제가 있고 게임의 코드는 한번에 실행되야 되는 명령이 작기 때문이다.

( Unity에서도 메인 스레드와 렌더 스레드 2개의 스레드를 사용했었는데, 각 스레드는 기능이 다르고 각 스레드간의 의존성이 떨어지기 때문에 가능한 것이였다. )

멀티 스레딩 문제를 해결하고 개발자가 쉽게 구현할 수 있도록 하기 위해 C#의 Job System을 Unity가 사용하였다.

● Job System

: 스레드를 대신하여 Job ( 단일 작업을 수행하는 가장 작은 단위 )을 만들어 멀리 스레드 코드를 관리한다.

( Job의 예를 들면 GameObject를 x 방향으로 +10 만큼 이동 시키는 작업을 말할 수 있다. )

▶ Job System은 여러 코어에 걸쳐 워커 스레드 그룹을 관리하는데, 스레드의 컨텍스트 스위칭이 발생하지 않도록 하기 위해 일반적으로 CPU 코어 하나당 1개의 워커 스레드를 생성한다. 

▶ Job System은 Job 대기열에 배치된 Job을 각 워커 스레드에게 분배하고 Job의 우선 순위를 설정해 순서대로 실행할 수 있도록 한다.

[ Job System 동작 원리 ]

▶ Job 을 생성할 때는 메인 스레드의 데이터를 Job의 Stack에 메모리 복사를 하여 사용하기 때문에 레이스 컨디션이 발생하지 않는다.

( 레퍼런스 타입도 데이터를 복사해서 사용하는데, 만약 메인 스레드의 데이터를 직접 접근하고 싶은 경우에는 NativeContainer라 불리는 공유 메모리 타입을 사용해야 한다. )

▶ Job System을 사용했을 때의 이 점은 게임에서 특정 캐릭터 100마리를 이동시켜야 한다고 했을 때 CPU 하나에서 처리할 경우 걸리는 N ( 1개의 움직임을 처리하는데 걸리는 시간 ) x 100이 아닌 N X ( 100 / Worker Thread ) 으로 성능이 향상되고 CPU 하나에 대한 부하를 줄임으로써 발열도 줄일수 있다는 것이다.

참고자료 : https://docs.unity3d.com/kr/2018.4/Manual/JobSystem.html

 

C# 잡 시스템 - Unity 매뉴얼

Unity C# 잡 시스템(Job System)을 사용해 Unity 엔진과 상호작용하는 간단하고 안전한 멀티스레드 코드를 작성하여 게임 성능을 개선할 수 있습니다.

docs.unity3d.com

참고자료 : https://www.youtube.com/watch?v=M1e9nmmD3II

참고자료 : https://www.youtube.com/watch?v=PXN8gpZ5OEg