C# Job System
Job System은 data에 안전하게 접근하면서 멀티 스레딩 코드를 구현할 수 있게 한다.
멀티 스레딩의 문제
안전한 코드를 짜기 힘들다
context switching이 비싸다
일반 Component System은 메인 스레드에서 돈다. 코어 수가 늘어나는 추세에 한 곳에서만 돌게 하는 것은 유용하지 않다. DOTS에 Job Component Systems (JCS)는 Job들을 Worker Thread에서 수행되도록 예약하는 일을 한다. (위 그림 참고)
// 예시
struct CopyFloatsJob : IJob
{
// Job에서 접근할 data를 모두 선언
// 안정성을 보장하기위해 읽기 전용 여부 선언
[ReadOnly]
public NativeArray<float> src;
public NativeArray<float> dst;
float deltaTime;
// Job에서 실행될 코드
public void Execute()
{
for(int i = 0; i < src.Length; i++)
dst[i] = src[i] * deltaTime;
}
}
var job = new CopyFloatsJob()
{
src = new NativeArray<float>(500, Allocator.Temp),
dst = new NativeArray<float>(500, Allocator.Temp),
deltaTime = Time.deltaTime
};
아래와 같이 Job이 끝나기 전에 인자를 수정하면 유니티 로그에 에러메시지가 뜬다.
JobHandle jobHandle = job.Schedule();
src[0] = 5;
...
// Complete the job ...
jobHandle.Complete();
다음과 같은 코드는 가능하다.
JobHandle jobHandle = job.Schedule();
...
// Complete the job ...
jobHandle.Complete();
src[0] = 5;
NOTE: NativeContainer
공유 메모리 타입. NativeContainer를 사용하면 잡이 복사본으로 작업하는 것이 아니라 메인 스레드와 공유되는 데이터에 액세스할 수 있다.
NativeContainer 관련 설명은 여기서 확인할 수 있음 here!
IJobParalleFor
여러개의 잡을 병렬로 실행할 수 있다.
struct CopyFloatsJobFor : IJobParalleFor
{
// Job에서 접근할 data를 모두 선언
// 안정성을 보장하기위해 읽기 전용 여부 선언
[ReadOnly]
public NativeArray<float> src;
public NativeArray<float> dst;
// Job에서 실행될 코드
public void Execute(int index)
{
dst[index] = src[index];
}
}
var job = new CopyFloatsJobFor()
{
src = new NativeArray<float>(500, Allocator.Temp);
dst = new NativeArray<float>(500, Allocator.Temp);
};
// job을 예약할때 amount of foreach & batch size 를 입력할 수 있다
job.Schedule(500, 100);
한 Job이 끝나고 다른 잡을 Schedule할 수 있다
// src -> dst 카피하는 잡 스케줄
var src = new NativeArray<float>(500, Allocator.Temp);
var dst = new NativeArray<float>(500, Allocator.Temp);
var jobA = new CopyFloatJobFor() {src = src; dst = dst};
var jobAHandle = jobA.Schedule(src.Length, 100);
// dst -> finalDst 카피하는 잡 스케줄
var finalDst = new NativeArray<float>(500, Allocator.Temp);
var jobB = new CopyFloatJobFor() {src = dst, dst = finalDst};
// jobAHandle의 dependency로 jobB를 스케줄한다.
var jobBHandle = jobB.Schedule(src.Length, 100, jobAHandle);
jobBHandle.Complete();
여기는 Unite Austin 2017 - Writing High Performance C# Scripts이걸 보고 간단히 정리한 것이라 자세히 보려면 unity manual을 보는 것이 좋을 것 같다.
'게임 개발 > 유니티 정보' 카테고리의 다른 글
[DOTS] Entity 크기 조정 어떻게 하는건가? 고민 기록 (0) | 2021.01.17 |
---|---|
[Unity] 프로젝트에 DOTS 적용하기. Hybrid ECS (+Entity Debugger) (0) | 2021.01.11 |
[Unity] DOTS란 무엇인가? Unity ECS 시스템 요약 (1) | 2021.01.09 |
최근댓글