기술 자료

Unity Engine

Unity Engine

NativeContainer 구조체 복사

Copy and reference multiple native containers.
읽는 시간 3분최근 업데이트: 한 달 전

네이티브 컨테이너는 값 유형이므로 변수에 할당되면 Unity는 네이티브 컨테이너의 데이터가 저장되는 위치(
AtomicSafetyHandle
포함)에 대한 포인터를 포함하는
NativeContainer
구조를 복사합니다.
NativeContainer
의 전체 내용을 복사하지는 않습니다.
이 시나리오는 모두 동일한 메모리 영역을 참조하고 모두 동일한 중앙 레코드를 참조하는
AtomicSafetyHandle
오브젝트를 포함한
NativeContainer
구조의 사본이 여러 개 있을 수 있음을 의미합니다.

NativeContainer 오브젝트 사본의 작동 방식

위의 다이어그램은 모두 동일한 실제 컨테이너를 나타내는
NativeArray
구조의 세 가지 사본을 보여 줍니다. 각 사본은 저장된 동일한 데이터 및 원본
NativeArray
와 동일한 안전 데이터를 가리킵니다. 그러나 각
NativeArray
의 사본에는 해당 사본으로 수행할 수 있는 잡을 나타내는 다른 플래그가 있습니다. 안전 데이터에 대한 포인터와 플래그가 결합되어
AtomicSafetyHandle
을 구성합니다.

버전 번호

NativeContainer
가 폐기되는 경우, 모든
NativeContainer
구조의 사본은 원본
NativeContainer
가 무효임을 인식해야 합니다. 원본
NativeContainer
의 폐기란
NativeContainer
의 데이터를 저장하는 데 사용된 메모리 블록이 할당 해제되었음을 의미합니다. 이 경우 각
NativeContainer
사본에 저장된 데이터에 대한 포인터가 유효하지 않으며 사용 시 액세스 위반이 발생할 수 있습니다.
또한
AtomicSafetyHandle
은
NativeContainer
인스턴스에 대해 무효화되는 중앙 기록을 가리킵니다. 하지만 안전 시스템은 중앙 레코드에 대한 메모리를 할당 해제하지 않으므로 액세스 위반의 위험을 방지합니다.
대신 각 기록에는 버전 번호가 포함됩니다. 해당 기록을 참조하는 각
AtomicSafetyHandle
내에 버전 번호 사본이 저장됩니다. NativeContainer가 폐기되면 Unity는
Release()
를 호출하여 중앙 기록의 버전 번호를 증가시킵니다. 그런 다음 다른
NativeContainer
인스턴스에 대해 기록을 재사용할 수 있습니다.
나머지
AtomicSafetyHandle 
은 각각 저장된 버전 번호와 중앙 기록의 버전 번호를 비교하여
NativeContainer
가 폐기되었는지 테스트합니다. Unity는
CheckReadAndThrow
및
CheckWriteAndThrow
와 같은 메서드 호출의 일환으로 이 테스트를 자동으로 수행합니다.

동적 네이티브 컨테이너의 정적 뷰

동적 네이티브 컨테이너는
NativeList<T>
(Collections 패키지에서 사용 가능)와 같이 요소를 계속 추가할 수 있는 변수 크기가 있는 컨테이너입니다. 이는 고정된 크기이며 변경할 수 없는
NativeArray<T>
와 같은 정적 네이티브 컨테이너와 다릅니다.
동적 네이티브 컨테이너를 사용하는 경우 뷰라는 다른 인터페이스를 통해 해당 데이터에 직접 액세스할 수도 있습니다. 뷰를 사용하면 데이터를 복사하거나 소유권을 취하지 않고도
NativeContainer
오브젝트의 데이터에 별칭을 지정할 수 있습니다. 뷰의 예로는 네이티브 컨테이너의 데이터에 요소별로 액세스하는 데 사용할 수 있는 열거자 오브젝트와
NativeList
를
NativeArray
처럼 취급하는 데 사용할 수 있는
NativeList<T>.AsArray
와 같은 메서드가 있습니다.
뷰는 일반적으로 동적 네이티브 컨테이너의 크기가 변경되는 경우 스레드에 안전하지 않습니다. 네이티브 컨테이너의 크기가 변경되면 Unity는 데이터가 메모리에 저장되는 위치를 재배치하므로 뷰에서 저장하는 모든 포인터가 무효화되기 때문입니다.

보조 버전 번호

동적 네이티브 컨테이너의 크기가 변경되는 상황을 지원하기 위해 안전 시스템은
AtomicSafetyHandle
에 보조 버전 번호를 포함합니다. 이 메커니즘은 버전 지정 메커니즘과 유사하지만, 중앙 기록에 저장된 두 번째 버전 번호를 사용하며 이는 첫 번째 버전 번호와 독립적으로 증분할 수 있습니다.
보조 버전 번호를 사용하려면
UseSecondaryVersion
을 사용하여
NativeContainer
에 저장된 데이터의 뷰를 설정할 수 있습니다. 네이티브 컨테이너의 크기를 변경하거나 기존 뷰를 무효화하는 작업의 경우
CheckWriteAndThrow
대신
CheckWriteAndBumpSecondaryVersion
을 사용합니다. 또한 네이티브 컨테이너에 쓰는 잡이 예약될 때마다 뷰가 자동으로 무효화되도록
NativeContainer
의
SetBumpSecondaryVersionOnScheduleWrite
도 설정해야 합니다.
뷰를 생성하고
AtomicSafetyHandle
을 뷰에 복사할 때
CheckGetSecondaryDataPointerAndThrow
를 사용하여 네이티브 컨테이너의 메모리에 대한 포인터를 뷰에 복사할 수 있는지 확인합니다.

특수 핸들

임시 네이티브 컨테이너로 작업할 때 사용할 수 있는 두 가지 특수 핸들이 있습니다.
  • GetTempMemoryHandle
    :
    Allocator.Temp
    로 할당된 네이티브 컨테이너에서 사용할 수 있는
    AtomicSafetyHandle
    을 반환합니다. 현재 임시 메모리 범위가 종료되면 Unity는 이 핸들을 자동으로 무효화하므로 직접 해제할 필요가 없습니다. 특정
    AtomicSafetyHandle
    이
    GetTempMemoryHandle
    에서 반환한 핸들인지 테스트하려면
    IsTempMemoryHandle
    을 사용합니다.
  • GetTempUnsafePtrSliceHandle
    : 안전하지 않은 메모리에서 지원되는 임시 네이티브 컨테이너에 사용 가능한 전역 핸들을 반환합니다. 예를 들면 스택 메모리로 구성된
    NativeSlice
    가 있습니다. 이 핸들을 사용하는 컨테이너는 잡에 전달할 수 없습니다.

추가 리소스