Dirección virtual de GPU

En este artículo se describen los conceptos de la dirección virtual de GPU (GPUVA) y cómo se administran a partir de WDDM 2.0 (Windows 10).

Las GPUVA se administran en páginas lógicas de 4 KB o 64 KB en el nivel de interfaz de controlador de dispositivo (DDI). El uso de estos tamaños de página permite que las GPUVA hagan referencia a:

  • Memoria del sistema, que siempre se asigna a una granularidad de 4 KB.
  • Las páginas del segmento de memoria se pueden gestionar en 4 KB o 64 KB.

El administrador de memoria de vídeo (VidMm) admite un esquema de traducción de direcciones virtuales de varios niveles, donde se usan varios niveles de tablas de páginas para traducir una dirección virtual:

  • Los niveles se numeran de cero. El nivel cero se asigna al nivel de hoja.
  • La traducción comienza desde la tabla de páginas de nivel raíz.

Cuando el número de niveles de tabla de páginas es dos, se puede cambiar el tamaño de la tabla de páginas de nivel raíz para dar cabida a un proceso con un tamaño de espacio gpuVA variable. Cada nivel se describe mediante la estructura DXGK_PAGE_TABLE_LEVEL_DESC que rellena el controlador de visualización en modo kernel (KMD) durante una llamada DxgkDdiQueryAdapterInfo. El KMD también rellena la estructura de límites DXGK_GPUMMUCAPS caps para describir la compatibilidad con GPUVA.

Cada proceso tiene su propio espacio de GPUVA. Antes de que se pueda establecer un contexto gráfico de un proceso para su ejecución, se llama a la función dxgkDdiSetRootPageTable de KMD para establecer la dirección de la tabla de página raíz.

La traducción de direcciones virtuales para el caso de dos niveles de tabla de páginas se muestra en el diagrama siguiente.

Diagrama que muestra la traducción de direcciones virtuales para dos niveles de tabla de páginas.

  • La GPUVA tiene DXGK_GPUMMUCAPSbits ::VirtualAddressBitCount bits.

  • Los bits bajos [0 - 11] representan un desplazamiento en bytes en una página.

  • Los siguientes bits DXGK_PAGE_TABLE_LEVEL_DESC::PageTableIndexBitCount representan el índice de una entrada de tabla de página en una tabla de nivel hoja.

  • El número de entradas de una tabla de páginas es 2DXGK_PAGE_TABLE_LEVEL_DESC::P ageTableIndexBitCount y el tamaño de la tabla de página es DXGK_PAGE_TABLE_LEVEL_DESC::PageTableSizeInBytes bytes.

  • El resto de los bits representan un índice a una entrada de una tabla de páginas en la tabla de páginas raíz. La tabla de página raíz se puede cambiar de tamaño para el esquema de traducción de dos niveles. La DDI de DxgkDdiGetRootPageTableSize obtiene su tamaño.

La estructura DXGK_PTE se usa a través del DDI para representar una entrada de tabla de páginas. Esta estructura representa información sobre cada entrada, que administra el kernel de gráficos de DirectX (Dxgkrnl). El controlador usa esta información para crear entradas de tabla de página específicas del hardware.

Creación de asignaciones de tablas de páginas

Las tablas de páginas se crean como asignaciones implícitas y no tienen un controlador en modo de usuario (UMD) ni un identificador KMD.

Para asignar una tabla de páginas, VidMm asigna una asignación de tamaño DXGK_PAGE_TABLE_LEVEL_DESC::PageTableSizeInBytes del segmento, especificado en DXGK_PAGE_TABLE_LEVEL_DESC::PageTableSegmentId. Después de la creación, VidMm inicializa cada entrada de la tabla de páginas a no válida. Las tablas de página nunca cambian el tamaño, excepto la tabla de página raíz del esquema de traducción de dos niveles.

VidMm admite el cambio de tamaño de la tabla de página raíz en el esquema de traducción de dos niveles. Cuando se crea una tabla de página raíz, que cubre una cantidad especificada de espacio de direcciones, VidMm llama a DxgkDdiGetRootPageTableSize para determinar el tamaño de asignación necesario para ella. A continuación, VidMm asigna una asignación de ese tamaño en el segmento, especificado por DXGK_PAGE_TABLE_LEVEL_DESC::PageTableSegmentId para el nivel raíz. Después de la creación, VidMm inicializa cada entrada de la tabla de páginas como inválida utilizando la nueva operación de paginación UpdatePageTable. La tabla de página raíz puede crecer o reducirse a medida que la cantidad de espacio de direcciones de vídeo que necesita un proceso se expande y se reduce. Una vez creada la tabla de página raíz, VidMm llama a DxgkDdiSetRootPageTable para asociar la tabla de página raíz recién creada con los distintos contextos que se ejecutarán dentro.

En las configuraciones del adaptador de pantalla vinculadas, las tablas de página raíz se crean como asignaciones de LinkMirrored. Estas asignaciones tienen contenido idéntico y se encuentran en la misma dirección física en cada GPU del vínculo. Las tablas de páginas de nivel inferior se asignan como asignación LinkInstanced para reflejar el hecho de que su contenido puede variar entre GPU, normalmente debido a una asignación del mismo nivel diferente. El contenido de las tablas de páginas se actualiza por separado en todas las GPU.

Crecimiento y reducción de una tabla de página raíz

Esta sección solo es aplicable a sistemas con dos niveles de tablas de páginas. Cuando el número de niveles de tabla de páginas es mayor que dos, el tamaño de la tabla de páginas para cada nivel se define mediante los límites de direccionamiento virtual y se fija.

Cuando el UMD solicita GPUVA, VidMm aumenta el tamaño del espacio de direcciones de un proceso para dar cabida a la solicitud. Para ello, aumenta el tamaño de la tabla de página raíz actual (si es necesario) y asigna nuevas tablas de páginas para el nuevo intervalo.

Para aumentar una tabla de página raíz VidMm crea otra asignación de tabla de página raíz, lo convierte en residente, inicializa sus entradas y destruye la asignación anterior. La función DxgkDdiGetRootPageTableSize se usa para obtener el tamaño de la nueva tabla de páginas en bytes.

Para reducir una tabla de página raíz, VidMm crea una nueva asignación de tabla de páginas, lo convierte en residente, copia una parte de la tabla de páginas antigua en la nueva y destruye la asignación anterior.

Una vez completada la operación de cambio de tamaño, VidMm llama a DxgkDdiSetRootPageTable para asociar los contextos afectados a su nueva tabla de página raíz.

Actualización de la tabla de páginas

A medida que las superficies se mueven en memoria, VidMm actualiza el contenido de las tablas de páginas para reflejar la nueva ubicación de las superficies.

Mover una tabla de páginas

* vidMm puede reubicar o expulsar tablas de páginas cuando un dispositivo está inactivo o suspendido. Cuando VidMm mueve una tabla de páginas, actualiza la tabla de páginas de niveles superiores para hacer referencia a la nueva ubicación de la tabla de páginas.

Cuando se reubica la propia tabla de página raíz, VidMm llama a DxgkDdiSetRootPageTable para informar a los contextos afectados de la nueva ubicación de su directorio de páginas.

Tamaño de página físico

Como se mencionó anteriormente, VidMm admite dos tamaños de página. La memoria del sistema siempre se administra en páginas de 4 KB, mientras que los segmentos de memoria se pueden administrar en granularidad de 4 KB o 64 KB según lo determinado por el KMD.

Al optar por que la memoria virtual se administre en páginas de 64 KB, todas las asignaciones se alinean automáticamente y tienen un tamaño de múltiplo de 64 KB.

La expansión de todas las asignaciones a 64 KB puede tener un efecto significativo en la memoria. UMD es responsable de empaquetar pequeñas asignaciones en una más grande para evitar desperdiciar memoria.

Cuando VidMm asigna una GPUVA a una página de segmento de memoria de 64 KB grande, asigna entradas de tabla de páginas de 4 KB a 16 páginas contiguas de 4 KB en el segmento de memoria. Se garantiza que la dirección virtual y la dirección física compartan la misma alineación de 64 KB. Es decir, se garantiza que los 16 bits inferiores de la dirección virtual y la dirección física coincidan.