Noções básicas sobre o desempenho da realidade misturada

Este artigo é uma introdução para entender a importância do desempenho para seu aplicativo Realidade Misturada. A experiência do usuário poderá ser muito degradada se o aplicativo não for executado a uma taxa de quadros ideal. Os hologramas parecerão instáveis e o acompanhamento da cabeça do ambiente será impreciso, levando a uma experiência ruim para o usuário. O desempenho deve ser considerado um recurso de primeira classe para o desenvolvimento de realidade misturada e não uma tarefa polida.

Os valores de taxa de quadros de desempenho para cada plataforma de destino estão listados abaixo.

Plataforma Taxa de Quadros de Destino
HoloLens 60 FPS
computadores Windows Mixed Reality Ultra 90 FPS
computadores Windows Mixed Reality 60 FPS

A estrutura a seguir descreve as práticas recomendadas para atingir as taxas de quadros de destino. Para obter dicas sobre como medir e melhorar a taxa de quadros no ambiente do Unity, recomendamos que você leia o artigo recomendações de desempenho do Unity

Noções básicas sobre gargalos de desempenho

Se o aplicativo tiver uma taxa de quadros de baixo desempenho, a primeira etapa será analisar e entender onde seu aplicativo é computacionalmente intensivo. Há dois processadores primários responsáveis pelo trabalho para renderizar sua cena: a CPU e a GPU, cada um lidando com diferentes aspectos do seu aplicativo Realidade Misturada. Os três principais locais onde podem ocorrer gargalos são:

  1. Thread do Aplicativo – CPU – responsável pela lógica do aplicativo, incluindo entrada de processamento, animações, física e outras lógicas de aplicativo.
  2. Renderizar Thread – CPU para GPU – responsável por enviar suas chamadas de desenho para a GPU. Quando seu aplicativo deseja renderizar um objeto como um cubo ou modelo, esse thread envia uma solicitação para a GPU para realizar as operações.
  3. GPU – geralmente manipula o pipeline gráfico do aplicativo para transformar dados 3D (modelos, texturas e assim por diante) em pixels. Em última análise, ele produz uma imagem 2D para enviar para a tela do dispositivo.

Tempo de vida de um quadro

Em geral, os aplicativos HoloLens serão associados à GPU, mas nem sempre. Use as ferramentas e técnicas abaixo para entender onde seu aplicativo específico está com gargalos.

Como analisar seu aplicativo

Há muitas ferramentas que permitem entender o perfil de desempenho e possíveis gargalos em seu aplicativo de realidade misturada.

Abaixo estão algumas ferramentas comuns para ajudá-lo a coletar informações de criação de perfil profundas para seu aplicativo:

Como criar o perfil em qualquer ambiente

Uma maneira de determinar se o aplicativo está associado à GPU ou à CPU é reduzir a resolução da saída de destino de renderização. Ao reduzir o número de pixels a serem calculados, você reduzirá a carga de GPU. O dispositivo será renderizado em uma textura menor e, em seguida, será exibido um exemplo para exibir sua imagem final.

Depois de reduzir a resolução de renderização, se:

  1. A taxa de quadros do aplicativo aumenta e, em seguida, é provável que você esteja associado à GPU
  2. Taxa de quadros do aplicativo inalterada e, em seguida, você provavelmente está associado à CPU

Observação

O Unity fornece a capacidade de modificar facilmente a resolução de destino de renderização de seu aplicativo em runtime por meio da propriedade XRSettings.renderViewportScale. A imagem final apresentada no dispositivo tem uma resolução fixa. A plataforma usará como amostra a saída de resolução mais baixa para criar uma imagem de resolução mais alta para renderização em visores.

UnityEngine.XR.XRSettings.renderScale = 0.7f;

Como melhorar seu aplicativo

Recomendações de desempenho da CPU

Geralmente, a maioria dos trabalhos em um aplicativo de realidade misturada na CPU envolve fazer a "simulação" da cena e processar a lógica do aplicativo. As seguintes áreas são destinadas à otimização:

  • Animações
  • Física
  • Alocações de memória
  • Algoritmos complexos (ou seja, cinemática inversa, localização de caminho)

Recomendações de desempenho da GPU

Noções básicas sobre largura de banda versus taxa de preenchimento

Ao renderizar um quadro na GPU, um aplicativo é limitado pela largura de banda de memória ou taxa de preenchimento.

  • Largura de banda de memória é a taxa de leituras e gravações que a GPU pode fazer da memória.
    • Para identificar limitações de largura de banda, reduza a qualidade da textura e marcar se a taxa de quadros melhorou.
    • Para identificar as limitações da taxa de preenchimento, reduza a resolução de exibição e veja se a taxa de quadros melhora.

Observação

Se você estiver trabalhando com o Unity, marcar nossas recomendações de desempenho de GPU específicas do Unity. - No Unity, use a propriedade XRSettings.renderViewportScale

A largura de banda de memória geralmente envolve otimizações para:

  1. Resoluções de textura mais baixas
  2. Usar menos texturas (normais, especular e assim por diante)

A taxa de preenchimento se concentra em reduzir o número de operações que precisam ser computadas para um pixel renderizado final, incluindo:

  1. Número de objetos a serem renderizados/processados
  2. Número de operações por sombreador
  3. Número de estágios de GPU para o resultado final (sombreadores de geometria, efeitos pós-processamento e assim por diante)
  4. Número de pixels a serem renderizados (resolução de exibição)

Reduzir a contagem de polígonos

Contagens de polígonos mais altas resultam em mais operações para a GPU, portanto, reduzir o número de polígonos em sua cena reduz o tempo de renderização. Há outros fatores que tornam o sombreamento da geometria caro, mas a contagem de polígonos é a métrica mais simples para determinar quanto trabalho será necessário para renderizar uma cena.

Limitar a sobreposição

A alta sobrecarga ocorre quando vários objetos são renderizados, mas não são mostrados na tela, pois estão ocultos por um objeto oclusão. Imagine olhar para uma parede que tem objetos atrás dela. Toda a geometria seria processada para renderização, mas apenas a parede opaca precisa ser renderizada, o que resulta em operações desnecessárias.

Sombreadores

Sombreadores são pequenos programas executados na GPU e executam duas etapas importantes na renderização:

  1. Determinando quais vértices devem ser desenhados e onde eles estão no espaço da tela (o sombreador de Vértice)
    • O sombreador de vértice é executado por vértice para cada malha.
  2. Determinando a cor de cada pixel (o sombreador pixel)
    • O sombreador Pixel é executado por pixel e renderizado pela geometria para a textura de renderização de destino.

Normalmente, sombreadores fazem muitas transformações e cálculos de iluminação. Embora modelos de iluminação complexos, sombras e outras operações possam gerar resultados fantásticos, eles também vêm com um preço. Reduzir o número de operações computadas em sombreadores pode reduzir consideravelmente o trabalho necessário para a GPU por quadro.

Recomendações de codificação de sombreador
  • Use a filtragem bilinear, sempre que possível
  • Reorganizar expressões para usar intrínsecos MAD para fazer uma multiplicação e um adição ao mesmo tempo
  • Pré-calcular o máximo possível na CPU e passar como constantes para o material
  • Favorecer a movimentação de operações do sombreador de pixel para o sombreador de vértice
    • Em geral, o número de vértices é muito menor do que o número de pixels (720p é 921.600 pixels, 1080p é 2.073.600 pixels e assim por diante)

Remover estágios de GPU

Os efeitos pós-processamento podem ser caros e aumentar a taxa de preenchimento do aplicativo, incluindo técnicas anti-aliasing como MSAA. No HoloLens, recomendamos evitar essas técnicas e estágios de sombreador adicionais, como geometria, casco e sombreadores de computação.

Recomendações de memória

Operações excessivas de alocação e desalocação de memória podem resultar em desempenho inconsistente, quadros congelados e outros comportamentos prejudiciais. É especialmente importante entender as considerações de memória ao desenvolver no Unity, pois o gerenciamento de memória é controlado pelo coletor de lixo.

Pool de objetos

O pool de objetos é uma técnica popular para reduzir o custo de alocações contínuas e desalocações de objetos. Isso é feito pela alocação de um grande pool de objetos idênticos e pela reutilização das instâncias disponíveis inativas desse pool em vez da criação e da destruição constantes de objetos ao longo do tempo. Os pools de objetos são ótimos para componentes reutilizados que têm um tempo de vida variável durante um aplicativo.

Confira também