Estratégias de gerenciamento de memória
Um gerenciador de memória para Direct3D 12 pode ficar muito complicado rapidamente com todas as diferentes camadas de suporte, para adaptadores UMA ou discretos (não UMA) e com uma gama considerável de diferenças de arquitetura entre adaptadores de GPU.
A estratégia recomendada para o gerenciamento de memória do Direct3D 12 , descrita nesta seção, é "classificar, orçamento e fluxo".
Tipos de recurso
O conceito básico de um "recurso confirmado" (criando espaços de endereço virtuais e físicos inicializados na memória física gerenciada) existe desde o Direct3D 9, embora o VA (endereçamento virtual) e o endereçamento físico possam ser separados no Direct3D 12 para permitir que o aplicativo gerencie cuidadosamente a memória física.
Além dos recursos confirmados, o constructo de heap do Direct3D 12 permite dois outros tipos de recurso: "colocado" e "reservado". No Direct3D 11, um recurso "reservado" era conhecido como "recurso lado a lado".
Os recursos reservados diferem dos recursos colocados, porque os recursos reservados têm seu próprio espaço de endereço virtual de GPU exclusivo. Isso permite uma grande alocação de espaço va antecipadamente e, em seguida, permite o mapeamento de páginas va para determinadas seções do heap mais tarde, e o aplicativo reconfigura a organização em tempo real. O espaço va é contíguo e pode ser pouco mapeado.
O recurso reservado pode ser feito para referenciar regiões no heap com chamadas à API, como UpdateTileMappings , e eles podem ser feitos residentes pelo aplicativo atualizando tabelas de páginas em tempo real. Quando um intervalo de VA é mapeado para NULL ou um heap não residente, essa parte do recurso é considerada não residente. Quando um intervalo de VA é mapeado para um heap residente, essa parte do recurso é considerada residente. Heaps são residentes na criação.
Os recursos colocados são um design muito mais simples, sendo simplesmente um ponteiro para uma determinada região de um heap (por exemplo, uma região de 1 Mb para uma textura em um heap de 5 Mb). As barreiras de alias permitem o uso de recursos colocados sobrepostos (consulte CreatePlacedResource e ResourceBarrier).
Os recursos reservados não estão disponíveis em todos os hardwares do Direct3D 12 e os recursos colocados são um fallback razoável, embora os recursos colocados precisem ser contíguos e não possam ser parcialmente residentes.
Orçamento de memória
No Direct3D 12, ao alocar um heap, você está criando o aspecto de memória física de um recurso confirmado. A opção de segmento de memória mais explícita está disponível no Direct3D 12 (escolhendo entre vídeo e memória do sistema). Os adaptadores UMA têm apenas um único segmento de memória, a memória do sistema.
As GPUs não dão suporte a falhas de página, portanto, os desenvolvedores devem estar conscientes de que não superam a confirmação, especialmente para sistemas que dizem com apenas 1 Gb de memória do sistema. Se um aplicativo fizer a confirmação em excesso, o sistema operacional usará o agendamento mais refinado de processos por sua demanda na memória física. O agendador congelará os processos em primeiro plano e essencialmente colocará alguns deles para fora, a fim de executar uma página em segundo plano que deseja executar. A memória física disponível pode variar consideravelmente dependendo do que o usuário está fazendo em segundo plano (como executar um navegador ou assistir a um vídeo).
A API para orçamento de memória é QueryVideoMemoryInfo. Para adaptadores discretos "local" é memória de vídeo, "não local" é memória do sistema. Para adaptadores UMA não locais é sempre zero. Uma questão de design é se o mecanismo gerenciará ambos os orçamentos ou apenas o orçamento local. O gerenciamento apenas do orçamento local é mais simples, mas tem algumas ressalvas; por exemplo, digamos que haja um orçamento local máximo de 1 Gb, então todos os heaps virão desse 1Gb em um sistema UMA e não há estouro na memória do sistema (claramente, como não há nenhum).
Como a memória gerenciada do Direct3D11 para aplicativos, os recursos não utilizados seriam essencialmente paginados.
Escolha as dimensões de recursos mais apropriadas. Considere se o tamanho de um recurso é apropriado para a situação em que o aplicativo está realmente em execução. Alguns usuários podem executar o aplicativo em uma janela ou com uma resolução de tela de 800x600.
Estratégia de classificação
Para gerenciar recursos efetivamente em cenários associados à memória, considere classificar os recursos para o seguinte:
classificação | Exemplos | Objetos e recursos de API | Notas de gerenciamento |
---|---|---|---|
Crítico | Interface do usuário do jogo | Alocador de comando, filas de comandos, heaps de consulta, recursos e heaps de recursos. | Esses elementos devem ir na memória não paginável/sempre confirmada. |
Dimensionado/opcional | Modelos e texturas específicos de nível, cadeias de troca, sky boxes, modelos de caracteres de jogador em primeira pessoa | Recursos e heaps. Os recursos confirmados, mas também colocados e reservados, também podem funcionar. | Integre o orçamento de residência de memória aos algoritmos de renderização. Escolha o nível apropriado de detalhes disponíveis e avalie novamente menos de uma vez por quadro. As técnicas incluem o uso de recursos de tamanho variável e o dimensionamento da cadeia de troca. |
Recursos usados novamente | Buffers de sombra, recursos de renderização adiados, recursos pós-processamento, caches de dados de iluminação | Recursos e heaps. Sobreposição de recursos colocados em heaps e barreiras de alias. | Reutilize recursos grandes ou regiões de heap dentro de um quadro para reduzir os requisitos de todo o quadro. Use a técnica de reutilização de memória intramoldura. No Direct3D 11, os aplicativos só podiam reutilizar recursos com o mesmo tipo e dimensões potencialmente grandes o suficiente. Os heaps do Direct3D 12 permitem recursos sobrepostos para reutilização muito mais simples e maior. |
Recursos de streaming | Terreno, texturas de mundo aberto e geometria | Recursos e heaps. Criação de thread livre, threads de CPU em segundo plano e filas e listas de comandos de cópia em segundo plano. | Residência parcial, geralmente com base na visibilidade (usando a avaliação baseada em exibição ou distância) e reavaliar as necessidades de residência em todos os quadros. A técnica de usar um gerenciamento de residência parcial por bloco e reutilização entre quadros está disponível quando o adaptador de GPU dá suporte a recursos reservados em heaps. Usando a técnica de usar a reutilização de memória entre quadros, a residência parcial de sub-recursos pode ser realizada, mas é menos ideal. Os recursos colocados com heaps devem habilitar a reciclagem mais rápida, mas os recursos confirmados podem ser usados como um fallback. |
Quanto mais aplicativos gravitarem para recursos de streaming durante a maior parte do trabalho, mais eles aproveitarão os recursos colocados e reservados, o que maximizará o reutilização da memória entre essas quatro classificações. Quanto mais aplicativos são transmitidos, mais eles têm orçamento e priorizam a largura de banda.
Normalmente, os mecanismos gráficos do Direct3D 12 precisam honrar um orçamento mais diversificado e dinâmico e fazê-lo mais estritamente do que no passado. Os melhores aplicativos localizarão todas as quatro categorias no orçamento dado ao processo, dimensionando o jogo do aplicativo móvel em segundo plano para orçamentos discretos de tela inteira. Mas, muitos aplicativos provavelmente terão dificuldades ao começar com muitos tipos críticos de categoria de recursos. O Direct3D 11 permitiu que os recursos fossem criados anonimamente e ocupassem status críticas sem afetar o desempenho. No entanto, para o Direct3D 12, os desenvolvedores devem pesquisar diligentemente recursos criados aleatoriamente em todo o mecanismo e middleware e reatribuí-los a uma das outras categorias.
Outras áreas problemáticas são componentes de middleware, controles de usuário e streaming dentro do quadro. Os componentes de middleware podem não ser expostos a um orçamento, nem precisam trabalhar firmemente juntos. Os componentes de middleware provavelmente podem expor recursos como técnicas de renderização; e o aplicativo pode depender da exposição de configurações de middleware e mecanismo. Os desenvolvedores podem contar com o Direct3D 11 para fazer a paginação e atingir a taxa de quadros correta. Em alguns casos, os aplicativos direct3D 11 podem ter paginado o conteúdo do recurso dentro e fora de cada quadro; e resultou em taxas de quadros aceitáveis para o usuário. A maioria dos mecanismos apenas transmite dados de recursos como uma atividade em segundo plano, em que não tem fallback normal para streaming intramoldura de alta prioridade. Pedir aos mecanismos que implementem isso corroerá alguns dos ganhos de sobrecarga da CPU que eles estão buscando mudando para o Direct3D 12. Os desenvolvedores de mecanismos podem considerar colocar seus quadros em fases para fornecer mais oportunidades para recursos reutilizáveis; e provavelmente funcionam com fornecedores de middleware para dar suporte a recursos e heaps colocados para reutilizações de memória intramoldura.