Analisar a programação de linhas de execução

É preciso considerar alguns pontos para determinar se as linhas de execução do processo do jogo estão sendo utilizadas e programadas corretamente para ter o melhor desempenho.

  • Frame Pacing
  • Uso de várias linhas de execução e carregamento em paralelo de linhas de execução
  • Afinidade do núcleo da CPU

Usar várias linhas de execução

Muitos jogos e mecanismos de jogos usam a multissegmentação para dividir o trabalho da CPU em tarefas lógicas, que podem ser executadas de forma independente. Uma configuração típica é uma linha de execução de jogo para lógica de entrada e de jogo, uma linha de execução de renderização para preparar e enviar objetos que serão desenhados e linhas de execução de worker para outras subtarefas, como animações ou áudio.

Recomendamos carregar as linhas de execução em paralelo para aproveitar os ganhos de desempenho do uso de várias linhas de execução. Um exemplo disso é um cenário em que as linhas de execução do jogo e de renderização estão sendo executadas parcial ou totalmente simultaneamente em núcleos diferentes. Isso nem sempre será possível, como em casos com dependências de dados compartilhadas. No entanto, quando possível, isso pode resultar em tempos de CPU mais baixos e, portanto, potencialmente mais frame rates.

Jogo com uma linha de execução principal e de renderização com paralelismo, bem como uma linha de execução de worker e uma linha de execução de áudio
Figura 1. Jogo com uma linha de execução principal e de renderização com paralelismo, bem como uma linha de execução de worker e uma linha de execução de áudio

Afinidade do núcleo da CPU

Um fator que afeta significativamente o desempenho das cargas de trabalho da CPU é a forma como elas são programadas nos núcleos. Ela pode ser dividida em dois componentes:

  • Se as linhas de execução do jogo estão sendo executadas no núcleo mais adequado para a carga de trabalho delas.
  • Se as linhas de execução do jogo alternam entre núcleos com frequência.

Os dispositivos modernos geralmente usam uma arquitetura chamada computação heterogênea, em que os núcleos têm diferentes níveis de desempenho:

  • Um ou alguns núcleos oferecem o melhor desempenho, mas consomem mais energia. Às vezes, eles são chamados de núcleos "grandes".
  • Outros núcleos têm um pico de desempenho menor, mas são mais eficientes em termos de energia. Às vezes, eles são chamados de núcleos "pequenos".
  • Opcionalmente, um ou mais núcleos oferecem um equilíbrio entre desempenho e potência. Às vezes, eles são chamados de núcleos "médios".

Você pode investigar o comportamento da linha de execução da CPU em Uso da CPU ativando a CPU na configuração do perfil ao fazer um trace. Ao aumentar o zoom em uma seção do rastro menor que 200 ms, é possível visualizar os processos individuais em execução nos núcleos da CPU do dispositivo. Normalmente, núcleos menores correspondem a índices menores (por exemplo, CPUs de 0 a 3), enquanto núcleos maiores correspondem a índices mais altos (por exemplo, CPUs de 6 a 7). núcleos intermediários, se presentes, ocuparão índices intermediários (por exemplo, CPUs de 5 a 6). Isso é uma convenção comum, mas não é uma garantia.

Se você achar que determinadas linhas de execução estão sendo programadas em CPUs que não atendem às necessidades de desempenho ou energia, defina manualmente a afinidade da CPU para essas linhas de execução.

Jogo com linha de execução principal e de renderização sendo executada principalmente nos núcleos grandes (CPU 6-7), mostrados em azul claro
Figura 2. Jogo com as linhas de execução principal e de renderização sendo executadas principalmente nos núcleos grandes (CPU 6-7), mostrados em azul claro.

Também é possível observar se as linhas de execução alternam entre os núcleos. Essas chaves principais geram sobrecarga da alternância de contexto e perda de estado com o cache/registros de um núcleo.

Jogo com linha de execução principal (Thread-7) e de renderização (Thread-8) que alternam entre núcleos, mostradas em roxo
Figura 3. Jogo com a linha de execução principal (Thread-7) e a linha de execução de renderização (Thread-8) que alternam entre núcleos, mostradas em roxo

A definição da afinidade da CPU para uma linha de execução instrui o sistema a programá-la no núcleo especificado quando o jogo estiver em primeiro plano. Há vários fatores que devem ser considerados ao fazer isso:

  • O software da plataforma não pode ajustar dinamicamente o posicionamento de tarefas para fatores de execução, como limitação de carga e térmica.
  • Os testes de desempenho em dispositivos diferentes podem gerar características de desempenho muito diferentes, especialmente se os dispositivos variarem consideravelmente por faixa de preço ou data de lançamento.

    Um dispositivo mais novo ou mais caro pode executar uma determinada carga de trabalho confortavelmente em um núcleo pequeno, mas um dispositivo mais antigo ou mais acessível pode exigir um núcleo maior para cumprir os prazos dessa mesma carga de trabalho.

  • Ao forçar afinidades para núcleos grandes, você pode aumentar desnecessariamente o consumo de bateria e a carga térmica.

Por esses motivos, geralmente é melhor evitar a configuração manual de afinidades de CPU.