Version: 2019.2
C# 잡 시스템의 안전 시스템
잡 만들기

NativeContainer

데이터 복사의 안전 시스템 프로세스에 대한 단점은 잡의 결과가 각 복사본 내에 격리된다는 것입니다. 이러한 제한을 극복하려면 결과를 NativeContainer라고 불리는 공유 메모리 타입에 저장해야 합니다.

NativeContainer란?

NativeContainer는 네이티브 메모리에 상대적으로 안전한 C# 래퍼를 제공하는 관리되는 값 타입입니다. 여기에는 관리되지 않는 할당에 대한 포인터가 들어 있습니다. Unity C# 잡 시스템과 함께 NativeContainer를 사용하면 잡이 복사본으로 작업하는 것이 아니라 메인 스레드와 공유되는 데이터에 액세스할 수 있습니다.

이용할 수 있는 NativeContainer 타입은?

Unity는 NativeArray라고 불리는 NativeContainer와 함께 제공됩니다. 또한 NativeSliceNativeArray를 조작하여 특정 포지션에서 NativeArray의 하위 집합을 특정 길이로 가져올 수도 있습니다.

참고: 엔티티 컴포넌트 시스템(ECS) 패키지는 다른 타입의 NativeContainer를 포함하도록 Unity.Collections 네임스페이스를 확장합니다.

  • NativeList - 크기 변경이 가능한 NativeArray입니다.
  • NativeHashMap - 키 및 값 쌍입니다.
  • NativeMultiHashMap - 키당 여러 개의 값입니다.
  • NativeQueue - 선입선출(FIFO) 대기열입니다.

NativeContainer 및 안전 시스템

안전 시스템은 모든 NativeContainer 타입에 내장되어 있으며, NativeContainer에 대한 읽기/쓰기 작업을 추적합니다.

참고: NativeContainer 타입에 대한 모든 안전 검사(예: 한도 검사, 할당 취소 검사, 경쟁 상태 검사)는 Unity EditorPlay Mode 에서 이용할 수 있습니다.

안전 시스템에는 DisposeSentinelAtomicSafetyHandle도 포함되어 있습니다. DisposeSentinel은 메모리 누수를 검사한 후 메모리를 잘못 할당한 경우 오류를 표시합니다. 메모리 누수 오류에 대한 트리거는 누수 후 오랜 시간이 지난 다음에 일어납니다.

AtomicSafetyHandle을 사용하면 코드로 NativeContainer의 소유권을 이전할 수 있습니다. 예를 들어, 두 개의 예약된 잡이 동일한 NativeArray에 작성하면 안전 시스템에서 예외가 발생하고 문제에 대한 이유 및 해결 방법을 설명하는 오류 메시지를 표시합니다. 문제가 되는 잡을 예약하면 안전 시스템에서 예외가 발생합니다.

이 경우 종속성을 사용하여 잡을 예약할 수 있습니다. 첫 번째 잡은 NativeContainer에 작성하고, 실행이 완료되면 다음 잡이 동일한 NativeContainer에 안전하게 작성하고 읽을 수 있습니다. 이러한 읽기/쓰기 제한은 메인 스레드에서 데이터에 액세스할 때도 적용됩니다. 안전 시스템을 사용하면 여러 작업이 동일한 데이터에서 병렬로 읽을 수 있습니다.

기본적으로 잡이 NativeContainer에 대한 액세스 권한을 가진 경우 읽기와 쓰기 모두를 수행할 수 있습니다. 이러한 설정은 성능 저하를 야기할 수 있습니다. C# 잡 시스템은 NativeContainer에 작성 중인 잡이 있을 때는 다른 잡에 쓰기 권한을 허용하지 않습니다.

잡이 NativeContainer에 작성할 필요가 없다면 [ReadOnly] 속성을 사용하여 다음과 같이 NativeContainer를 표시하십시오.

[ReadOnly]
public NativeArray<int> input;

위 예에서는 첫 번째 NativeArray에 대한 읽기 전용 액세스 권한이 있는 다른 잡과 동시에 잡을 실행할 수 있습니다.

참고: 잡 내에서 정적 데이터에 대한 액세스는 보호되지 않습니다. 정적 데이터에 액세스하면 모든 안전 시스템을 우회하므로 Unity에 크래시가 발생할 수 있습니다. 자세한 내용은 C# 잡 시스템 팁 및 문제 해결을 참조하십시오.

NativeContainer 할당자

NativeContainer를 만들 때는 필요한 메모리 할당 타입을 지정해야 합니다. 할당 타입은 잡 실행 시간에 따라 다릅니다. 이렇게 하면 할당을 맞춤 설정하여 각 상황에서 최고의 성능을 끌어낼 수 있습니다.

NativeContainer 메모리 할당 및 릴리스에는 세 가지의 할당자 타입을 이용할 수 있습니다. NativeContainer를 인스턴스화할 때 적절한 타입을 지정해야 합니다.

  • Allocator.Temp는 가장 빠른 할당입니다. 수명이 1프레임 이하인 할당에 적합합니다. Temp를 사용하여 잡에 NativeContainer 할당을 전달하면 안 됩니다. 또한 메서드 호출(예: MonoBehaviour.Update 또는 네이티브에서 관리되는 코드로의 기타 다른 콜백)을 반환하기 전에 Dispose 메서드를 호출해야 합니다.
  • Allocator.TempJobTemp보다는 느리지만 Persistent보다는 빠른 할당입니다. 수명이 4프레임 이하인 할당에 적합하며 스레드 세이프 기능을 지원합니다. 4프레임 내에서 Dispose 메서드를 호출하지 않으면 콘솔은 네이티브 코드로 생성된 경고를 출력합니다. 대부분의 소규모 잡은 이 NativeContainer 할당 타입을 사용합니다.
  • Allocator.Persistent는 가장 느린 할당이지만, 애플리케이션의 주기에 걸쳐 필요한 만큼 오래 지속됩니다. malloc에 대한 직접 호출을 위한 래퍼입니다. 오래 걸리는 잡은 이 NativeContainer 할당 타입을 사용할 수 있습니다. 성능이 중요한 상황에서는 Persistent를 사용하지 않아야 합니다.

예제:

NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);

참고: 위 예제에서 숫자 1은 NativeArray의 크기를 나타냅니다. 이 경우에는 하나의 어레이 요소만 보유하고 있습니다(하나의 데이터 조각만 result에 저장함).


  • 2018–06–15

  • 2018.1에서 공개된 C# 잡 시스템 NewIn20181

C# 잡 시스템의 안전 시스템
잡 만들기