메모리 관리 전략

Direct3D 12용 메모리 관리자는 다양한 지원 계층, UMA 또는 불연속(비 UMA) 어댑터 및 GPU 어댑터 간의 아키텍처 차이가 상당히 다양하여 매우 복잡해질 수 있습니다.

이 섹션에서 설명하는 Direct3D 12 메모리 관리에 권장되는 전략은 "분류, 예산 및 스트림"입니다.

리소스 종류

"커밋된 리소스"(관리되는 실제 메모리에서 초기화된 가상 및 물리적 주소 공간 모두 만들기)의 기본 개념은 Direct3D 9부터 사용되어 왔지만, 앱이 실제 메모리를 신중하게 관리할 수 있도록 Direct3D 12에서 VA(가상 주소 지정) 및 물리적 주소 지정을 따로 처리할 수 있습니다.

커밋된 리소스 외에도 Direct3D 12의 힙 구문을 사용하면 다른 두 가지 유형의 리소스인 "배치"와 "예약됨"을 사용할 수 있습니다. Direct3D 11에서는 "예약된" 리소스를 "타일형 리소스"라고 했습니다.

예약된 리소스는 예약된 리소스에 고유한 GPU 가상 주소 공간이 있다는 점에서 배치된 리소스와 다릅니다. 이렇게 하면 VA 공간을 미리 대량으로 할당한 다음 나중에 VA 페이지를 힙의 특정 섹션에 매핑할 수 있으며 애플리케이션은 즉시 정렬을 다시 구성합니다. VA 공간은 연속되며 드물게 매핑될 수 있습니다.

예약된 리소스는 UpdateTileMappings 같은 API 호출을 사용하여 힙의 지역을 참조하도록 만들 수 있으며, 즉석에서 페이지 테이블을 업데이트하여 앱에 상주할 수 있습니다. VA 범위가 NULL 또는 비거주 힙에 매핑되는 경우 리소스의 해당 부분은 비거주로 간주됩니다. VA 범위가 상주 힙에 매핑되면 리소스의 해당 부분이 상주하는 것으로 간주됩니다. 힙은 생성 시 상주합니다.

배치된 리소스는 힙의 특정 영역(예: 5Mb 힙의 텍스처에 대한 1Mb 영역)에 대한 포인터일 뿐이므로 훨씬 간단한 디자인입니다. 별칭 장벽을 사용하면 겹치는 배치된 리소스를 사용할 수 있습니다(CreatePlacedResourceResourceBarrier참조).

예약된 리소스는 모든 Direct3D 12 하드웨어에서 사용할 수 없으며 배치된 리소스는 적절한 대체(fallback)이지만 배치된 리소스는 연속되어야 하며 부분적으로 상주할 수 없습니다.

메모리 예산

Direct3D 12에서 힙을 할당할 때 커밋된 리소스의 실제 메모리 측면을 만듭니다. 더 명시적인 메모리 세그먼트 선택은 Direct3D 12(비디오 및 시스템 메모리 중에서 선택)에서 사용할 수 있습니다. UMA 어댑터에는 단일 메모리 세그먼트, 시스템 메모리만 있습니다.

GPU는 페이지 오류를 지원하지 않으므로 개발자는 커밋을 초과하지 않는다는 것을 의식해야 하며, 특히 시스템 메모리가 1Gb에 불과하다고 말하는 시스템에는 주의해야 합니다. 앱이 커밋을 초과하면 OS는 실제 메모리에 대한 수요에 따라 프로세스의 거친 일정 예약을 사용합니다. 스케줄러는 포그라운드 프로세스를 동결하고 기본적으로 실행하려는 백그라운드 프로세스를 페이즈 인하기 위해 그 중 일부를 페이즈 아웃합니다. 사용 가능한 실제 메모리는 사용자가 백그라운드에서 수행하는 작업(예: 브라우저 실행 또는 비디오 시청)에 따라 상당히 달라질 수 있습니다.

메모리 예산에 대한 API는 QueryVideoMemoryInfo. 불연속 어댑터 "local"이 비디오 메모리인 경우 "비 로컬"은 시스템 메모리입니다. UMA 어댑터의 경우 로컬이 아닌 어댑터는 항상 0입니다. 한 가지 디자인 질문은 엔진이 예산을 둘 다 관리할지 아니면 현지 예산만 관리할 것인지 여부입니다. 로컬 예산만 관리하는 것이 더 간단하지만 몇 가지 주의 사항이 있습니다. 예를 들어 1Gb의 최대 로컬 예산이 있다고 가정하면 모든 힙은 UMA 시스템의 해당 1Gb에서 가져오며 시스템 메모리에 오버플로가 없습니다(없음).

애플리케이션에 대한 Direct3D11 관리 메모리이므로 사용하지 않는 리소스는 기본적으로 페이징됩니다.

가장 적절한 리소스 차원을 선택합니다. 리소스 크기가 애플리케이션이 실제로 실행 중인 상황에 적합한지 여부를 고려합니다. 일부 사용자는 창에서 또는 화면 해상도가 800x600인 애플리케이션을 실행할 수 있습니다.

분류 전략

메모리 바인딩 시나리오에서 리소스를 효과적으로 관리하려면 리소스를 다음으로 분류하는 것이 좋습니다.

분류 예제 개체 및 API 기능 관리 참고 사항
비판적인 게임 UI 명령 할당자, 명령 큐, 쿼리 힙, 리소스 및 리소스 힙. 이러한 요소는 페이징할 수 없는/항상 커밋된 메모리로 이동해야 합니다.
크기 조정/선택 사항 수준별 모델 및 텍스처, 스왑 체인, 스카이 박스, 1인칭 플레이어 캐릭터 모델 리소스 및 힙. 커밋된 리소스뿐만 아니라 배치 및 예약된 리소스도 작동할 수 있습니다. 메모리 상주 예산을 렌더링 알고리즘에 통합합니다. 적절한 수준의 사용 가능한 세부 정보를 선택하고 프레임당 두 번 미만의 다시 평가합니다. 기술에는 가변 크기 리소스 사용 및 스왑 체인 크기 조정이 포함됩니다.
다시 사용되는 리소스 섀도 버퍼, 지연 렌더링 리소스, 후처리 리소스, 조명 데이터 캐시 리소스 및 힙. 힙 및 별칭 장벽에 배치된 리소스가 겹칩니다. 프레임 내에서 큰 리소스 또는 힙 영역을 다시 사용하여 전체 프레임에 대한 요구 사항을 줄입니다. 프레임 내 메모리 재사용 기술을 사용합니다. Direct3D 11에서 애플리케이션은 동일한 형식과 잠재적으로 충분한 차원의 리소스만 다시 사용할 수 있습니다. Direct3D 12 힙을 사용하면 겹치는 리소스를 훨씬 더 간단하고 더 쉽게 재사용할 수 있습니다.
스트리밍 리소스 지형, 오픈 월드 텍스처 및 기하 도형 리소스 및 힙. 자유 스레드 만들기, 백그라운드 CPU 스레드 및 백그라운드 복사 명령 큐 및 목록. 일반적으로 가시성(보기-frustum 또는 거리 기반 평가 사용)을 기반으로 하는 부분 상주 및 재평가 상주에는 모든 프레임이 필요합니다.
GPU 어댑터가 힙 내에서 예약된 리소스를 지원하는 경우 타일별 부분 상주 관리 및 프레임 간 재사용을 사용하는 기술을 사용할 수 있습니다.
프레임 간 메모리를 다시 사용하는 기술을 사용하여 부분 하위 리소스 보존을 수행할 수 있지만 최적이 아닌 경우 힙이 있는 배치된 리소스는 더 빠른 재활용을 가능하게 하지만 커밋된 리소스는 대체(fallback)로 사용할 수 있습니다.

대부분의 작업에서 스트리밍 리소스에 더 많은 애플리케이션이 몰두할수록 배치된 리소스와 예약된 리소스를 더 많이 활용하므로 이러한 네 가지 분류 간에 메모리 재사용이 최대화됩니다. 애플리케이션 스트림이 많을수록 예산을 더 많이 책정하고 대역폭의 우선 순위를 지정합니다.

일반적으로 Direct3D 12 그래픽 엔진은 보다 다양하고 역동적인 예산을 준수해야 하며, 이전보다 더 엄격하게 수행해야 합니다. 최상의 애플리케이션은 프로세스에 지정된 예산으로 네 가지 범주를 모두 찾아 백그라운드 모바일 앱에서 전체 화면 불연속 예산으로 게임 플레이를 확장합니다. 그러나 많은 애플리케이션은 너무 많은 중요한 범주 유형의 리소스로 시작하여 어려움을 겪을 수 있습니다. Direct3D 11을 사용하면 성능에 영향을 주지 않고 리소스를 익명으로 만들고 중요한 상태를 차지할 수 있습니다. 그러나 Direct3D 12의 경우 개발자는 엔진 및 미들웨어 전체에서 임의로 생성된 리소스를 부지런히 검색하고 다른 범주 중 하나에 다시 할당해야 합니다.

다른 문제 영역으로는 미들웨어 구성 요소, 사용자 컨트롤 및 프레임 내 스트리밍이 있습니다. 미들웨어 구성 요소는 예산에 노출되지 않거나 긴밀하게 함께 작업할 필요가 없습니다. 미들웨어 구성 요소는 렌더링 기술로 기능을 노출할 수 있습니다. 애플리케이션은 미들웨어 및 엔진 설정을 노출하는 데 의존할 수 있습니다. 개발자는 Direct3D 11을 사용하여 페이징을 수행하고 적절한 프레임 속도를 달성할 수 있습니다. 경우에 따라 Direct3D 11 애플리케이션이 모든 프레임의 리소스 콘텐츠를 페이징하고 있을 수 있습니다. 그리고 그것은 사용자에 대 한 허용 프레임 속도 결과. 대부분의 엔진은 리소스 데이터를 백그라운드 작업으로만 스트리밍하며, 우선 순위가 높은 프레임 내 스트리밍으로 정상적으로 대체되지 않습니다. 엔진에 이를 구현하도록 요청하면 Direct3D 12로 이동하여 원하는 CPU 오버헤드 증가의 일부가 침식됩니다. 엔진 개발자는 재사용 가능한 리소스에 대한 더 많은 기회를 제공하기 위해 프레임을 단계로 괴롭히는 것을 고려할 수 있습니다. 미들웨어 공급업체와 협력하여 프레임 내 메모리 재사용을 위해 배치된 리소스 및 힙을 지원할 수 있습니다.

CreateCommittedResource

CreateReservedResource

Direct3D 12 프로그래밍 가이드

메모리 관리

리소스 바인딩