게임엔진/유니티

(토막상식) NativeContainer

tsyang 2023. 5. 28. 13:16

Native Container


Native Container는  native memory(unmanage)에 대한 wrapper이다. (Thread-Safe를 지원) native memory에 대한 버퍼를 managed code영역으로 노출하는 array, map, set등을 가지고 있음. 기본적으로는 Safety-Check를 수행하는데, unsafe로 시작하는 애들은 안 함. 그래서 당연히 native를 쓰는 게 더 좋겠지만 Native Container안에 Native Container를 담을 수는 없어서 unsafe를 써야 할 때가 있긴 하다.

 

Access 정해주기

기본적으로 job 따위가 NativeContainer 인스턴스에 접근하면 read/write 둘 다 가능함. 그러나 이건 비효율적인데 read만 하는 애들은 read만 한다고 명시해주면 더 좋다.(당연히 lock이 덜 걸리니까) 이런 경우에 [ReadOnly] 어트리뷰트를 달아줄 수 있음.

 

 

Allocator

Allocator에는 3가지 종류가 있음. {Temp, TempJob, Persistent} 그리고 다음과 같이 씀.

NativeArray<int> nums = new NativeArray<int>(10, Allocator.TempJob);

Temp 가 가장 빠르고, Persistent가 가장 느리다.

 

Allocator.Temp : 1프레임 이하의 수명을 갖는 할당. 이런 container는 job에 넘겨줄 수 없음. 메 프레임마다 메인 쓰레드가 temp allocator를 만들고, 프레임이 끝날 때 다 deallocate함. Job도 쓰레드마다 하나의 Temp Allocator를 만들고, job이 끝날때 deallocate함. 따라서 유저가 deallocate할 필요 없음. minimum alignment는 64바이트 단위.

 

Allocator.TempJob : 4프레임의 수명을 갖는 할당. 4프레임 안에 Dispose를 콜해줘야 함.만약 native컨테이너라면 4프레임 안에 dispose를 호출 안하면 익셉션을 던짐. unsafe의 경우에도 4프레임 안에 해야하는 건 맞는데 유니티가 오류를 던져주지는 않음. minimum alignment는 16바이트. 

 

Allocator.Persistent : 말 그대로 영구적, 유니티가 수명에 대한 safety-check를 수행하지 않음. 따라서 사용자가 잘 쓰고 dispose도 해줘야함. minimum alignment는 16바이트. 

 


https://docs.unity3d.com/2023.2/Documentation/Manual/JobSystemNativeContainer.html

https://docs.unity3d.com/Packages/com.unity.collections@2.1/manual/allocator-overview.html