스레드 세이프 유형
Understand Unity's custom thread-safe type, NativeContainer.
읽는 시간 3분최근 업데이트: 한 달 전
잡 시스템은 버스트 컴파일러와 함께 사용할 때 가장 잘 작동합니다. 버스트는 관리되는 오브젝트를 지원하지 않으므로 관리되지 않는 유형을 사용하여 잡의 데이터에 액세스해야 합니다. 이 작업은 블리터블 유형을 사용하거나 네이티브 메모리에 대한 스레드 세이프 C# 래퍼인 Unity의 빌트인 오브젝트를 사용하여 수행할 수 있습니다. 또한 오브젝트를 사용하면 잡이 복사본으로 작업하는 대신 메인 스레드와 공유되는 데이터에 액세스할 수 있습니다.
NativeContainerNativeContainerNativeContainers 유형
Unity.CollectionsNativeContainer- : 네이티브 메모리의 버퍼를 관리되는 코드에 노출하는 관리되지 않는 배열
NativeArray - : 특정 위치에서 특정 길이로
NativeSlice의 하위 집합 가져오기NativeArray
읽기 및 쓰기 액세스
기본적으로 잡이 인스턴스에 액세스할 수 있는 경우 읽기 및 쓰기 권한이 있습니다. 이러한 설정으로 인해 성능이 저하될 수 있습니다. 이는 잡 시스템이 인스턴스에 쓰기 액세스 권한이 있는 잡을 해당 인스턴스에 쓰고 있는 다른 잡과 동시에 예약할 수 없기 때문입니다.
NativeContainerNativeContainer하지만 잡이 인스턴스에 작성하지 않아도 된다면 속성을 사용하여 다음과 같이 를 표시할 수 있습니다.
NativeContainer[ReadOnly]NativeContainer[ReadOnly]public NativeArray<int> input;
위 예에서는 첫 번째 에 대한 읽기 전용 액세스 권한이 있는 다른 잡과 동시에 잡을 실행할 수 있습니다.
NativeArray메모리 할당자
NativeContainer NativeContainerNativeContainer- : 가장 빠른 할당입니다. 수명이 1프레임 이하인 할당에 사용합니다. 잡의 멤버 필드에 저장된
Allocator.Temp인스턴스에 할당을 전달하기 위해NativeContainer를 사용할 수 없습니다.Temp - :
Allocator.TempJob보다 느리지만Temp보다 빠른 할당입니다. 4프레임의 수명 내에서 스레드 세이프 할당에 사용합니다. 중요: 4프레임 이내에 이 할당 유형을Persistent해야 합니다. 그렇지 않으면 콘솔이 네이티브 코드에서 생성된 경고를 출력합니다. 대부분의 소규모 잡은 이 할당 유형을 사용합니다.Dispose - : 할당 속도가 가장 느리지만, 필요할 경우 애플리케이션의 수명 기간 동안 필요한 만큼 오래 사용할 수 있습니다.
Allocator.Persistent에 대한 직접 통화를 위한 래퍼입니다. 더 긴 잡은 이 NativeContainer 할당 유형을 사용할 수 있습니다. 성능이 필수적인 경우에는malloc를 사용하지 마십시오.Persistent
예시:
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
참고: 위 예시의 숫자 1은 NativeArray의 크기를 나타냅니다. 이 경우 결과에 하나의 데이터 조각만 저장하므로 배열 요소가 하나뿐입니다.
NativeContainer 안전 시스템
모든 인스턴스에 내장된 보안 시스템입니다. 이 시스템은 어떤 인스턴스에 읽거나 쓰는 것을 추적하고, 해당 정보를 사용하여 여러 잡과 스레드에서 결정적인 방식으로 행동하는 의 사용에 대한 특정 규칙을 적용합니다.
NativeContainerNativeContainerNativeContainer예를 들어 두 개의 독립적으로 예약된 잡이 동일한 에 쓰면 어떤 잡이 먼저 실행되는지 예측할 수 없기 때문에 안전하지 않습니다. 즉, 어느 잡이 다른 잡의 데이터를 덮어쓰는지 알 수 없습니다. 이 보안 시스템은 두 번째 잡을 예약할 때 문제가 해결되는 이유와 방법을 설명하는 명확한 오류 메시지가 포함된 예외를 발생시킵니다.
NativeArray동일한 인스턴스에 쓰는 두 개의 잡을 예약하려면 종속성으로 잡을 예약합니다. 첫 번째 잡은 에 쓰며, 실행이 끝나면 다음 잡은 같은 에 안전하게 읽고 쓰게 됩니다. 종속성을 도입하면 잡이 항상 일관된 순서로 실행되고 의 결과 데이터가 결정론적임을 보장할 수 있습니다.
NativeContainerNativeContainerNativeContainerNativeContainer안전 시스템을 통해 여러 잡이 동일한 데이터에서 동시에 읽을 수 있습니다.
메인 스레드에서 데이터에 액세스하는 경우에도 이러한 읽기 및 쓰기 제한이 적용됩니다. 예를 들어 NativeContainer에 쓰는 작업이 완료되기 전에 NativeContainer의 콘텐츠를 읽으려고 하면 안전 시스템에서 오류가 발생합니다. 마찬가지로 읽거나 쓰는 잡이 보류 중인 상태에서 NativeContainer에 쓰기를 시도하면 안전 시스템에서도 오류가 발생합니다.
또한 NativeContainer는 을 구현하지 않으므로 의 내용을 직접 변경할 수 없습니다. 예를 들어 는 에서 값을 업데이트하지 않는 를 작성하는 것과 같습니다.
ref returnNativeContainernativeArray[0]++;nativeArrayvar temp = nativeArray[0]; temp++;대신에 인덱스의 데이터를 로컬 임시 복사본으로 복사하고 해당 복사본을 수정한 후 다시 저장해야 합니다. 예시:
MyStruct temp = myNativeArray[i];temp.memberVariable = 0;myNativeArray[i] = temp;