Compartir a través de


Procedimientos recomendados de administración de recursos

Las texturas administradas, también conocidas como administración automática de texturas, están disponibles en DirectX desde la versión 6, con varias revisiones y mejoras realizadas en versiones posteriores. A partir de la versión de la API de Direct3D 9, la administración automática de recursos incluye compatibilidad con texturas, búferes de vértices e índices, todo ello con una interfaz compartida coherente. Mediante el uso del administrador de recursos de Direct3D, las aplicaciones pueden simplificar considerablemente el control de situaciones de dispositivo perdido y pueden confiar en el sistema para controlar una cantidad razonable de exceso de compromiso de los recursos de memoria de vídeo.

A veces, los desarrolladores tienen dificultades para usar recursos administrados, en parte debido a la naturaleza abstracta del sistema. Aunque muchos escenarios comunes para los recursos son una buena opción para los recursos administrados, algunos casos funcionan mejor al usar recursos no administrados. En este artículo se describen los procedimientos recomendados para tratar los recursos con carácter general, cómo se comportan los recursos administrados y no administrados, y se proporciona información detallada sobre cómo normalmente administran los recursos en tiempo de ejecución y los controladores.

En este artículo se tratan estos conceptos:

Memoria de vídeo

Para que el sistema de vídeo use un recurso, debe estar ubicado en la memoria a la que se puede acceder a la GPU. La memoria de vídeo local proporciona el mejor rendimiento para la GPU y determinados recursos (como destinos de representación y búferes de profundidad o galería de símbolos) deben encontrarse en la memoria de vídeo local. Con la llegada de AGP, la GPU también puede acceder directamente a una parte de la memoria del sistema. Este área de memoria, conocida como apertura AGP, se conoce como memoria de vídeo no local y no está disponible para otros fines. La CPU puede leer y escribir en la memoria de vídeo no local, que normalmente no tiene acceso de alto rendimiento a la memoria de vídeo local y, por tanto, es ideal para su uso como recurso de memoria compartida. Lo importante que hay que recordar sobre la memoria de AGP es que, como la memoria de vídeo local, se invalida en situaciones de dispositivo perdido y los recursos persistentes ubicados allí deben restaurarse.

Figura 1. Relación de la GPU, la CPU, la RAM de vídeo y la RAM del sistema

relación de la gpu, cpu, ram de vídeo y ram del sistema

Algunas soluciones de vídeo integradas usan una arquitectura de memoria unificada (UMA), donde la memoria principal es direccionable por todos los componentes de los sistemas. Direct3D admite UMA sin necesidad de ningún cambio en la aplicación, utilizando las mismas sugerencias que para las configuraciones de memoria de vídeo local. Para estos sistemas, los recursos siempre se encuentran en la memoria del sistema y el controlador es responsable de garantizar que los recursos funcionen de forma muy similar a lo que hacen en una arquitectura más tradicional, al tiempo que aprovechan las propiedades de UMA y cualquier comportamiento específico de la implementación de hardware.

Ilustración 2. La GPU y la CPU tienen acceso igual a la RAM del sistema en una arquitectura de memoria unificada

Gpu y cpu tienen acceso igual a la ram del sistema en una arquitectura de memoria unificada

Recursos administrados

La mayoría de los recursos se deben crear como recursos administrados en POOL_MANAGED. Todos los recursos se crearán en la memoria del sistema y, a continuación, se copiarán según sea necesario en la memoria de vídeo. Las situaciones de dispositivo perdido se controlarán automáticamente desde la copia de memoria del sistema. Dado que no todos los recursos administrados deben ajustarse a la memoria de vídeo a la vez, puede confirmar en exceso la memoria donde un conjunto de trabajo de memoria de vídeo más pequeño de recursos es todo lo que se necesita para representarse en cualquier fotograma determinado. Tenga en cuenta que es probable que la mayoría de esta memoria del sistema de memoria auxiliar se paginará en el disco con el tiempo, por lo que la operación de restablecimiento puede ser lenta debido a la necesidad de volver a paginar estos datos para restaurar la memoria de vídeo perdida.

El tiempo de ejecución mantiene una marca de tiempo por última vez que se usa un recurso y, cuando se produce un error en la asignación de memoria de vídeo para cargar un recurso administrado necesario, liberará los recursos en función de esta marca de tiempo de forma LRU. El uso de SetPriority tiene prioridad sobre la marca de tiempo, por lo que los recursos más usados deben establecerse en un valor de prioridad más alto. Direct3D 9.0 tiene información limitada sobre la memoria de vídeo administrada por el controlador, por lo que es posible que el tiempo de ejecución tenga que expulsar varios recursos para crear una región lo suficientemente grande como para que la asignación se realice correctamente. Las prioridades adecuadas pueden ayudar a eliminar situaciones en las que se expulsa algo y, a continuación, se requiere de nuevo poco después. La aplicación también puede llamar a EvictManagedResources para forzar la eliminación de todos los recursos administrados. De nuevo, esto puede llevar mucho tiempo para volver a cargar todos los recursos necesarios para el siguiente fotograma, pero es muy útil para las transiciones de nivel en las que el espacio de trabajo cambia significativamente y para quitar la fragmentación de memoria de vídeo.

También se mantiene un recuento de fotogramas para permitir que el tiempo de ejecución detecte si el recurso que acaba de elegir expulsar se usó al principio del fotograma actual, lo que implica una situación de limitación en la que hay más recursos en uso en un solo fotograma que cabe en la memoria de vídeo. Esto desencadena la directiva de reemplazo para cambiar a una moda de MRU en lugar de LRU para el resto del marco, ya que esto tiende a funcionar ligeramente mejor en tales condiciones. Este comportamiento de limitación afectará significativamente al rendimiento de la representación. Tenga en cuenta que la noción de marco actual está vinculada a EndScene, por lo que cualquier aplicación que use recursos administrados debe realizar llamadas normales a este método.

Los desarrolladores que buscan encontrar más información sobre cómo se comportan los recursos administrados en su aplicación pueden usar la consulta de eventos RESOURCEMANAGER a través de la interfaz IDirect3DQuery9 . Esto solo funciona cuando se usan los entornos de ejecución de depuración, por lo que la aplicación no puede depender de esta información, pero proporciona detalles detallados sobre los recursos administrados por el tiempo de ejecución.

Aunque comprender cómo funciona el administrador de recursos puede ayudar a optimizar y depurar las aplicaciones, es importante no vincular la aplicación demasiado estrechamente a los detalles de implementación del entorno de ejecución o los controladores actuales. Las revisiones del controlador o los cambios en el hardware pueden cambiar significativamente el comportamiento y las versiones futuras de Direct3D tendrán una administración de recursos significativamente mejorada y sofisticada.

recursos de Driver-Managed

Los controladores de Direct3D son gratuitos para implementar la funcionalidad de texturas administradas por el controlador, indicada por D3DCAPS2_CANMANAGERESOURCE, lo que permite al controlador controlar la administración de recursos en lugar del tiempo de ejecución. Para el controlador (raro) que implementa esta característica, el comportamiento exacto del administrador de recursos del controlador puede variar ampliamente, y debe ponerse en contacto con el proveedor del controlador para obtener más información sobre cómo funciona para su implementación. Como alternativa, puede asegurarse de que siempre se usa el administrador en tiempo de ejecución especificando D3DCREATE_DISABLE_DRIVER_MANAGEMENT al crear el dispositivo.

Recursos predeterminados

Aunque los recursos administrados son simples, eficientes y fáciles de usar, hay ocasiones en que el uso de la memoria de vídeo directamente es preferido o incluso necesario. Estos recursos se crean en la categoría POOL_DEFAULT. El uso de estos recursos provoca complicaciones adicionales para la aplicación. El código es necesario para hacer frente a la situación de dispositivo perdido para todos los recursos de POOL_DEFAULT y se deben tener en cuenta las consideraciones de rendimiento al copiar datos en ellos. Si no se especifica USAGE_WRITEONLY o se puede bloquear un destino de representación, también se pueden imponer penalizaciones graves de rendimiento.

Llamar a Lock en un recurso de POOL_DEFAULT es más probable que la GPU se detenga que trabajar con un recurso de POOL_MANAGED, a menos que use determinadas marcas de sugerencias. Dependiendo de la ubicación del recurso, el puntero devuelto podría ser a un búfer de memoria del sistema temporal o puede ser un puntero directamente en la memoria de AGP. Si se trata de un búfer temporal de memoria del sistema, los datos deberán transferirse a la memoria de vídeo después de la llamada de desbloqueo . Si el recurso de vídeo no es de solo escritura, los datos tendrán que transferirse al búfer temporal durante el bloqueo. Si se trata de un área de memoria de AGP, se evitan las copias temporales, pero el comportamiento de la memoria caché necesario puede dar lugar a un rendimiento lento.

Se debe tener cuidado de escribir una línea de datos de caché completa en cualquier puntero a la memoria de apertura de AGP para evitar la penalización de la combinación de escritura, lo que induce un ciclo de lectura y escritura, y se prefiere el acceso secuencial del área de memoria. Si la aplicación necesita tener acceso aleatorio a los datos durante la creación y no desea usar un recurso administrado para el búfer, debe trabajar con una copia de memoria del sistema en su lugar. Una vez creados los datos, puede transmitir el resultado a la memoria de recursos bloqueada para evitar pagar una penalización alta para la operación de combinación de escritura en caché.

La marca LOCK_NOOVERWRITE se puede usar para anexar datos de forma eficaz para algunos recursos, pero lo ideal es que se eviten varias llamadas de bloqueo y desbloqueo al mismo recurso. Hacer un uso adecuado de las distintas marcas de bloqueo es importante para un rendimiento óptimo, ya que se usa un patrón descriptivo de caché de acceso a datos al rellenar la memoria bloqueada.

Uso de recursos administrados y predeterminados

La combinación de asignaciones de recursos administrados y POOL_DEFAULT puede provocar la fragmentación de memoria de vídeo y confundir la vista del tiempo de ejecución de la memoria de vídeo disponible para los recursos administrados. Lo ideal es crear todos los recursos POOL_DEFAULT antes de usar POOL_MANAGED recursos o usar la llamada EvictManagedResources antes de asignar recursos no administrados. Recuerde que todas las asignaciones realizadas a partir de POOL_DEFAULT que residen en la memoria de vídeo vinculan la memoria durante la vida útil que el recurso no está disponible para su uso por parte del administrador de recursos o para cualquier otro propósito.

Tenga en cuenta que, a diferencia de las versiones anteriores de Direct3D, el tiempo de ejecución de la versión 9 expulsa automáticamente algunos recursos administrados antes de renunciar a una asignación de recursos no administrada con errores por falta de memoria de vídeo, pero esto puede crear fragmentación adicional e incluso forzar un recurso en una ubicación sub óptima (por ejemplo, tener una textura estática en memoria de vídeo no local). De nuevo, es mejor asignar todos los recursos no administrados necesarios por adelantado y antes de usar los recursos administrados.

Recursos predeterminados dinámicos

Los datos que se generan y actualizan con una frecuencia alta no necesitan el almacenamiento auxiliar, ya que toda la información se volverá a crear al restaurar el dispositivo. Normalmente, estos datos se crean mejor en POOL_DEFAULT, especificando la sugerencia USAGE_DYNAMIC, de modo que el controlador pueda tomar decisiones de optimización al colocar el recurso, sabiendo que se actualizará con frecuencia. Normalmente, esto significa colocar el recurso en memoria de vídeo no local y, por lo tanto, suele ser mucho más lento para que la GPU acceda a la memoria de vídeo local. En el caso de las arquitecturas de UMA, el controlador puede elegir una ubicación determinada para los recursos dinámicos para optimizar el acceso de escritura de CPU.

Este uso es típico para las soluciones de máscara de software y los sistemas de partículas basados en CPU que rellenan búferes de vértices o índices, y la marca LOCK_DISCARD garantizará que no se creen puestos en los casos en los que el recurso todavía está en uso desde el marco anterior. El uso de un recurso administrado en este caso actualizaría un búfer de memoria del sistema, que luego se copiaría en la memoria de vídeo y, a continuación, se usaría solo para un fotograma o dos antes de reemplazarse. En el caso de los sistemas con memoria de vídeo no local, la copia adicional se elimina mediante el uso adecuado de este patrón dinámico.

Las texturas estándar no se pueden bloquear y solo se pueden actualizar a través de UpdateSurface o UpdateTexture. Algunos sistemas admiten texturas dinámicas, que se pueden bloquear y usar el patrón de LOCK_DISCARD, pero se debe comprobar un bit de funcionalidad (D3DCAPS2_DYNAMICTEXTURES) antes de usar dichos recursos. Para texturas altamente dinámicas (vídeo o procedimientos), la aplicación podría crear POOL_DEFAULT coincidentes y POOL_SYSTEMMEM recursos y controlar las actualizaciones de memoria de vídeo mediante UpdateTexture. Para actualizaciones muy frecuentes y parciales, es probable que el paradigma updateTexture sea la mejor opción.

Tan útil como pueden ser los recursos dinámicos, tenga cuidado al diseñar sistemas que dependen en gran medida del envío dinámico. Los recursos estáticos deben colocarse en POOL_MANAGED para garantizar un buen uso de la memoria de vídeo local y para hacer un uso más eficaz del ancho de banda de memoria principal y el bus limitado. En el caso de los recursos semiestáticos, es posible que el costo de una carga ocasional en la memoria de vídeo local sea mucho menor que el tráfico de bus constante generado al convertirlos en dinámicos.

Recursos de memoria del sistema

Los recursos también se pueden crear en POOL_SYSTEMMEM. Aunque la canalización de gráficos no las puede usar, se pueden usar como orígenes para actualizar POOL_DEFAULT recursos mediante UpdateSurface o UpdateTexture. Su comportamiento de bloqueo es sencillo, aunque pueden producirse detenerse si están en uso por uno de los métodos mencionados anteriormente.

Aunque residen en la memoria del sistema, POOL_SYSTEMMEM recursos se limitan a los mismos formatos y funcionalidades (como el tamaño máximo) admitidos por el controlador de dispositivo. El tipo de recurso POOL_SCRATCH es otra forma de recurso de memoria del sistema que puede usar todos los formatos y funcionalidades compatibles con el tiempo de ejecución, pero no puede tener acceso al dispositivo. Los recursos de scratch están diseñados principalmente para su uso por las herramientas de contenido.

Figura 3. Recursos de memoria en ram de vídeo, apertura de AGP y RAM del sistema

recursos de memoria en ram de vídeo, apertura de agp y ram del sistema

Recomendaciones generales

La obtención de los detalles técnicos de implementación de la administración de recursos correcta hará un largo camino hacia lograr los objetivos de rendimiento de la aplicación. Planear cómo se presentan los recursos a Direct3D y el diseño arquitectónico en torno a la obtención de los datos cargados de forma oportuna es una tarea más complicada. Se recomienda una serie de procedimientos recomendados al tomar estas decisiones para la aplicación:

  • Procese previamente todos los recursos. Confiar en la conversión de tiempo de carga y la optimización costosas para los recursos es conveniente durante el desarrollo, pero hacerlo pone una gran carga de rendimiento en los equipos de los usuarios. Los recursos procesados previamente son más rápidos de cargar, más rápido de usar y ofrecen la opción de realizar un trabajo sofisticado fuera de línea.
  • Evite crear muchos recursos por fotograma. Las interacciones del controlador necesarias pueden serializar la CPU y la GPU, y las operaciones implicadas son pesadas, ya que a menudo requieren transiciones de kernel. Distribuya la creación en varios fotogramas o reutilice recursos sin crearlos ni liberarlos. Idealmente, debe esperar varios fotogramas antes de bloquear o liberar recursos que se usaron recientemente para representar.
  • Al final del marco, asegúrese de desenlace de todos los canales de recursos (es decir, orígenes de flujos, fases de textura e índices actuales). De este modo, se asegurará de que se quiten las referencias pendientes a los recursos antes de que el administrador de recursos mantenga los recursos residentes que ya no están en uso.
  • En el caso de las texturas, use formatos comprimidos (por ejemplo, DXTn) con mapas mip y considere la posibilidad de usar un atlas de texturas. Estos requisitos de ancho de banda reducen considerablemente y pueden reducir el tamaño general de los recursos, lo que los hace más eficientes.
  • En el caso de la geometría, use la geometría indizada, ya que esto ayuda a comprimir los recursos del búfer de vértices y el hardware de vídeo moderno está optimizado en torno a la reutilización de vértices. Al usar sombreadores de vértices programables, puede comprimir la información del vértice y expandirla durante el procesamiento del vértice. De nuevo, esto ayuda a reducir los requisitos de ancho de banda y hace que los recursos del búfer de vértices sean más eficaces.
  • Evite la sobre optimización de la administración de recursos. Las revisiones futuras de los controladores, el hardware y el sistema operativo pueden causar problemas de compatibilidad si la aplicación se ajusta demasiado a una combinación especialmente. Dado que la mayoría de las aplicaciones están enlazadas a la CPU, la administración costosa basada en CPU generalmente provoca más problemas de rendimiento que los que resuelve.

Administrar recursos

Dispositivos perdidos

Optimizaciones de rendimiento

Recursos de textura comprimidos

Consultas

D3DUSAGE

D3DPOOL

D3DCREATE