GPU 가상 주소

이 문서에서는 GPU 가상 주소(GPUVA) 개념과 WDDM 2.0(Windows 10)부터 GPU 가상 주소가 어떻게 관리되는지 설명합니다.

GPUVA는 DDI(디바이스 드라이버 인터페이스) 수준에서 논리적 4KB 또는 64KB 페이지로 관리됩니다. 이러한 페이지 크기를 사용하면 GPUVA에서 다음 중 하나를 참조할 수 있습니다.

  • 시스템 메모리는 항상 4KB 세분성으로 할당됩니다.
  • 4KB 또는 64KB로 관리할 수 있는 메모리 세그먼트 페이지입니다.

비디오 메모리 관리자(VidMm)는 여러 수준의 페이지 테이블을 사용하여 가상 주소를 변환하는 다단계 가상 주소 변환 체계를 지원합니다.

  • 수준은 0부터 번호가 매겨집니다. 레벨 0은 리프 레벨에 할당됩니다.
  • 변환은 루트 수준 페이지 테이블에서 시작됩니다.

페이지 테이블 수준 수가 2이면 GPUVA 공간 크기가 가변적인 프로세스를 수용하도록 루트 수준 페이지 테이블의 크기를 조정할 수 있습니다. 모든 수준은 DxgkDdiQueryAdapterInfo 호출 중에 KMD(커널 모드 디스플레이 드라이버)가 채우는 DXGK_PAGE_TABLE_LEVEL_DESC 구조에 의해 설명됩니다. 또한 KMD는 GPUVA 지원을 설명하기 위해 DXGK_GPUMMUCAPS 캡 구조를 작성합니다.

각 프로세스에는 고유한 GPUVA 공간이 있습니다. 프로세스의 그래픽 컨텍스트를 실행하도록 설정하기 전에 KMD의 DxgkDdiSetRootPageTable 함수가 호출되어 루트 페이지 테이블 주소를 설정합니다.

두 페이지 테이블 수준의 사례에 대한 가상 주소 변환은 다음 다이어그램에 나와 있습니다.

두 페이지 테이블 수준에 대한 가상 주소 변환을 보여 주는 다이어그램

  • GPUVA에는 DXGK_GPUMMUCAPS::VirtualAddressBitCount 비트가 있습니다.

  • 하위 비트 [0 - 11]는 페이지의 오프셋(바이트)을 나타냅니다.

  • 다음 DXGK_PAGE_TABLE_LEVEL_DESC::PageTableIndexBitCount 비트는 리프 레벨 페이지 테이블 내의 페이지 테이블 항목 인덱스를 나타냅니다.

  • 페이지 테이블의 항목 수는 2DXGK_PAGE_TABLE_LEVEL_DESC::PageTableIndexBitCount이고, 페이지 테이블 크기는 DXGK_PAGE_TABLE_LEVEL_DESC::PageTableSizeInBytes 바이트입니다.

  • 나머지 비트는 루트 페이지 테이블의 페이지 테이블 항목에 대한 인덱스를 나타냅니다. 루트 페이지 테이블은 2단계 변환 구성표에 대해 크기를 조정할 수 있습니다. DxgkDdiGetRootPageTableSize DDI는 그 크기를 가져옵니다.

DXGK_PTE 구조체는 DDI를 통해 페이지 테이블 항목을 나타내는 데 사용됩니다. 이 구조는 DirectX 그래픽 커널(Dxgkrnl)이 관리하는 각 항목에 대한 정보를 나타냅니다. 드라이버는 이 정보를 사용하여 하드웨어별 페이지 테이블 항목을 작성합니다.

페이지 테이블 할당 생성

페이지 테이블은 암시적 할당으로 생성되며 UMD(사용자 모드 드라이버) 또는 KMD 핸들이 없습니다.

페이지 테이블을 할당하려면 VidMmDXGK_PAGE_TABLE_LEVEL_DESC::PageTableSegmentId에서 지정된 세그먼트로부터 DXGK_PAGE_TABLE_LEVEL_DESC의 크기로PageTableSizeInBytes 할당을 수행합니다. 만든 후 VidMm 페이지 테이블의 모든 항목을 초기화하여 잘못된. 2단계 변환 체계의 루트 페이지 테이블을 제외하고 페이지 테이블의 크기는 변경되지 않습니다.

VidMm 2단계 변환 체계에서 루트 페이지 테이블의 크기 조정을 지원합니다. 지정된 주소 공간을 포함하는 루트 페이지 테이블을 만들 때, VidMm은 필요한 할당 크기를 결정하기 위해 DxgkDdiGetRootPageTableSize를 호출합니다. VidMmDXGK_PAGE_TABLE_LEVEL_DESC에 의해 지정된 세그먼트에 해당 크기의 할당을 합니다. 루트 레벨에 대해서는PageTableSegmentId 를 지정합니다. 만든 후 VidMmUpdatePageTable 페이징 작업을 사용하여 페이지 테이블의 모든 항목을 무효로 초기화합니다. 프로세스에 필요한 비디오 주소 공간의 양이 확장 및 축소됨에 따라 루트 페이지 테이블이 증가하거나 축소될 수 있습니다. 루트 페이지 테이블이 만들어지면 VidMmDxgkDdiSetRootPageTable를 호출하여 새로 만든 루트 페이지 테이블을 실행될 다양한 컨텍스트와 연결합니다.

연결된 디스플레이 어댑터 구성에서 루트 페이지 테이블은 LinkMirrored 할당으로 만들어집니다. 이러한 할당은 동일한 콘텐츠를 가지며 링크의 각 GPU에서 동일한 실제 주소에 있습니다. 하위 수준의 페이지 테이블은 피어 매핑의 차이로 인해 GPU마다 콘텐츠가 달라질 수 있음을 반영하여 및 LinkInstanced 방식으로 할당됩니다. 페이지 테이블의 콘텐츠는 모든 GPU에서 별도로 업데이트됩니다.

루트 페이지 테이블 증가 및 축소

이 섹션은 두 가지 수준의 페이지 테이블이 있는 시스템에만 적용됩니다. 페이지 테이블 수준 수가 2보다 크면, 각 수준의 페이지 테이블 크기는 가상 주소 지정에 의한 제한으로 정의되며 고정됩니다.

UMD가 GPUVA를 요청하면 VidMm 요청을 수용하기 위해 프로세스의 주소 공간 크기가 증가합니다. 이렇게 하려면 현재 루트 페이지 테이블의 크기를 늘리고(필요한 경우) 새 범위에 대한 새 페이지 테이블을 할당합니다.

VidMm 다른 루트 페이지 테이블 할당을 만들고, 상주하고, 항목을 초기화하고, 이전 할당을 삭제하는 루트 페이지 테이블을 확장합니다. DxgkDdiGetRootPageTableSize 함수는 새 페이지 테이블의 크기를 바이트 단위로 가져오는 데 사용됩니다.

루트 페이지 테이블을 축소하려면 VidMm 새 페이지 테이블 할당을 만들고, 상주하도록 만들고, 이전 페이지 테이블의 일부를 새 페이지 테이블에 복사하고, 이전 할당을 삭제합니다.

크기 조정 작업 완료 후 VidMmDxgkDdiSetRootPageTable 호출을 통해 영향을 받는 컨텍스트를 새 루트 페이지 테이블과 연결합니다.

페이지 테이블 업데이트

표면이 메모리에서 이동함에 따라 VidMm 새 표면 위치를 반영하도록 페이지 테이블의 콘텐츠를 업데이트합니다.

페이지 테이블 이동

* VidMm 디바이스가 유휴 상태이거나 일시 중단된 경우 페이지 테이블을 재배치하거나 제거할 수 있습니다. VidMm 페이지 테이블을 이동하면 페이지 테이블의 새 위치를 참조하도록 상위 수준 페이지 테이블이 업데이트됩니다.

루트 페이지 테이블 자체가 재배치되면, VidMmDxgkDdiSetRootPageTable를 호출하여 영향을 받는 컨텍스트에 새로운 페이지 디렉터리 위치를 알립니다.

실제 페이지 크기

앞에서 설명한 것처럼 VidMm 두 페이지 크기를 지원합니다. 시스템 메모리는 항상 4KB 페이지에서 관리되지만 메모리 세그먼트는 KMD에 의해 결정된 대로 4KB 또는 64KB 세분성으로 관리할 수 있습니다.

64KB 페이지에서 가상 메모리를 관리하도록 선택하면 모든 할당이 자동으로 정렬되고 크기가 64KB의 배수로 조정됩니다.

모든 할당을 64KB로 확장하면 메모리에 상당한 영향을 미칠 수 있습니다. UMD는 메모리 낭비를 방지하기 위해 작은 할당을 더 큰 할당으로 압축하는 작업을 담당합니다.

VidMm이 GPUVA를 대형 64KB 메모리 세그먼트 페이지에 매핑하면, 4KB 페이지 테이블 항목을 메모리 세그먼트 내 16개의 연속된 4KB 페이지에 매핑합니다. 가상 주소와 실제 주소는 동일한 64KB 정렬을 공유하도록 보장됩니다. 즉, 가상 주소와 실제 주소의 하위 16비트가 일치하도록 보장됩니다.