EveryDay.DevUp

[Unity] Job 시스템 이해, IJob - (1) 본문

DotsTween

[Unity] Job 시스템 이해, IJob - (1)

EveryDay.DevUp 2020. 7. 15. 20:12

● Unity의 Job 시스템에 대한 이해가 필요하다면, 다음의 게시물을 참고 

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

 

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

ECS를 알아보기 전 DOTS에 대해 궁금한 점이 있다면 하단의 링크를 통해 알아 볼 수 있다. https://everyday-devup.tistory.com/67 [Unity] DOTS ( Data Oriented Technology Stack ) ● DOTS란? ▶ Unity를 통해..

everyday-devup.tistory.com

● Unity의 Job 시스템을 사용했을 때의 장점을 확인 하고 싶다면, 다음의 게시물을 참고

https://everyday-devup.tistory.com/96?category=952300

 

[Unity] Update() vs Job, Burst 성능 비교

ITween은 MonoBehaviour의 Update() 를 통해 Tween이 동작하는데, DotsTween도 동일하게 Update() 를 사용하지만 Job, Burst를 구현하여 동작하는 방식을 사용한다. ITween에서 동작하는 방식이 Job,Burst 보다..

everyday-devup.tistory.com

Unity의 Job 시스템을 이용하기 위해서는 using Unity.Jobs 를 사용해야 한다.

해당 게시글에서는 Unity.Jobs의 코드 확인 및 샘플 프로젝트를 만들어 봄으로써 Job 시스템을 이해하고자 한다.

[ Unity.Jobs 의 계층 구조 ]

● Interface IJob

▶ 단일 작업을 하는 Job을 구현 할 때, struct에 상속하는 interface

[JobProducerType( typeof( IJobExtensions.JobStruct<> ) )]
public interface IJob
{
	//
	// 요약:
	//     Implement this method to perform work on a worker thread.
	void Execute();
}

▶ Execute() 함수에 Job에서 진행할 코드를 작성, 단일 Worker 스레드에서 Execute()가실행됨

▶ Execute() 에는 parameter 값이 없기 때문에, 구조체에 사용할 값을 넣어서 사용해야 함

▶ IJob을 상속 받아,  a + b를 구현한 Job의 예제 코드

using UnityEngine;
using Unity.Jobs;
using Unity.Collections;

public class JobSample : MonoBehaviour
{
	/// <summary>
	/// a + b 를 더하여 result에 값을 넎는 단순한 Job 예제
	/// </summary>
	struct JobSigle : IJob
	{
		/// <summary>
		/// Job 에서 사용할 수 있는 변수는 값 타입
		/// </summary>
		public int a;
		public int b;

		/// <summary>
		/// 메인 스레드와 메모리를 공유하기 위해서는 NativeContainer라는 특수한 변수를 사용해야함 
		/// </summary>
		public NativeArray<int> result;

		/// <summary>
		/// 워커 스레드에서 실행되는 함수 
		/// </summary>
		public void Execute()
		{
			result[0] = a + b;
		}
	}

	void Start()
	{
		/// Job을 생성한 후 a, b에 값을 할당
		JobSigle jobSigle = new JobSigle();
		jobSigle.a = 1;
		jobSigle.b = 2;
		/// 메인 스레드에서 값을 사용하기 위해 NativeArray를 선언 
		jobSigle.result = new NativeArray<int>( 1, Allocator.TempJob );

		/// Job을 실행 할 수 있도록 워커 스레드에 예약함, 
		/// 메인 스레드에서는 Schedule만 호출 할 수 있음
		JobHandle handle = jobSigle.Schedule();

		/// JobSingle이 완료되기 전까지 메인스레드가 동작하지 않도록 
		/// Complete를 선언 할 수 있음. Complete를 선언함으로써 Job의 실행이 완료 된 후 
		/// 메인스레드에서 안전하게 NativeContainer에 접근할 수 있음
		handle.Complete();

		Debug.LogWarning( " result : " + jobSigle.result[0] );

		/// NativeContainer를 사용한 후에는 Dispose를 호출해서 메모리에서 삭제해야함.
		/// Dispose를 호출하지 않으면 Unity에서 에러를 냄 
		jobSigle.result.Dispose();
	}
}

: Job을 사용하지 않았다면, 코드 한줄로 작성이 가능하지만 Job을 사용하면 처리할 코드와 이해할 내용이 많아진다. 대신 그만큼 성능도 향상된다.

※ 후속 게시물 ( NativeContainer )

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

 

[Unity] Job 시스템 이해, NativeContainer - (2)

※ NativeContainer를 보기 전, Job 시스템의 이해가 필요하다면 하단의 게시물을 참고 https://everyday-devup.tistory.com/97 [Unity] Job 시스템 이해, IJob - (1) ● Unity의 Job 시스템에 대한 이해가 필요..

everyday-devup.tistory.com

참고 자료 

https://docs.unity3d.com/kr/current/Manual/JobSystem.html