Identificar instabilidade relacionada à capacidade

A capacidade é a quantidade total de algum recurso (CPU, GPU etc.) que um dispositivo possui ao longo de um período. Esta página descreve como identificar e resolver problemas de instabilidade relacionados à capacidade.

O governador demora a reagir.

Para evitar instabilidade, o regulador de frequência da CPU precisa ser capaz de responder rapidamente a cargas de trabalho com bursts. A maioria dos apps de interface segue o mesmo padrão básico:

  1. O usuário está lendo a tela.
  2. O usuário toca na tela: toca em um botão, rola a tela etc.
  3. A tela rola, muda de atividade ou é animada de alguma forma em resposta à entrada.
  4. O sistema fica inativo quando o novo conteúdo é exibido.
  5. O usuário volta a ler a tela.

Os dispositivos Pixel e Nexus implementam o aumento de toque para modificar o comportamento do governador de frequência da CPU (e do agendador) ao tocar. Para evitar uma rampa lenta para uma frequência de relógio alta (que pode fazer com que o dispositivo perca frames ao tocar), o aumento de toque normalmente define um piso de frequência na CPU para garantir que haja muita capacidade de CPU disponível ao tocar. Um piso dura por algum tempo após o toque (geralmente cerca de dois segundos).

O Pixel também usa o cgroup schedtune fornecido pela programação com economia de energia (EAS, na sigla em inglês) como um sinal de aumento de toque extra: os principais apps recebem mais peso pelo schedtune para garantir que eles tenham capacidade de CPU suficiente para serem executados rapidamente. O Nexus 5X e o 6P têm uma diferença de desempenho muito maior entre os clusters de CPU pequenos e grandes (A53 e A57, respectivamente) do que o Pixel com a CPU Kryo. Descobrimos que o pequeno cluster de CPU não era sempre adequado para renderização suave da interface, especialmente considerando outras fontes de jitter no dispositivo.

Assim, no Nexus 5X e 6P, o aumento de toque modifica o comportamento do programador para aumentar a probabilidade de os apps em primeiro plano serem movidos para os núcleos grandes. Isso é conceitualmente semelhante ao piso na frequência da CPU. Sem a mudança do programador para aumentar a probabilidade de apps em primeiro plano serem movidos para o cluster de CPU grande, os apps em primeiro plano podem ter capacidade de CPU insuficiente para renderização até que o programador decida balancear a linha de execução em um núcleo de CPU grande. Ao mudar o comportamento do programador durante o aumento de toque, é mais provável que uma linha de execução da interface seja executada imediatamente em um núcleo grande e evite o travamento, sem forçar que ela seja executada sempre em um núcleo grande, o que poderia ter impactos graves no consumo de energia.

Limitação térmica

O throttling térmico ocorre quando o dispositivo precisa reduzir a saída térmica geral, geralmente realizada pela redução de clocks de CPU, GPU e DRAM. Não é de surpreender que isso geralmente resulte em instabilidade, já que o sistema pode não conseguir mais fornecer capacidade suficiente para renderizar em um determinado intervalo de tempo. A única maneira de evitar o limite térmico é usar menos energia. Não há muitas maneiras de fazer isso, mas, com base em nossas experiências com SOCs anteriores, temos algumas recomendações para fornecedores de sistemas.

Primeiro, ao criar um novo SOC com arquiteturas de CPU heterogêneas, verifique se as curvas de desempenho/W dos clusters de CPU se sobrepõem. A curva de desempenho/W geral de todo o processador precisa ser uma linha contínua. As descontinuidades na curva de desempenho/W forçam o programador e o regulador de frequência a adivinhar o que uma carga de trabalho precisa. Para evitar o jank, o programador e o regulador de frequência erram ao dar à carga de trabalho mais capacidade do que ela precisa. Isso resulta em um consumo excessivo de energia, o que contribui para a limitação térmica.

Imagine um SOC hipotético com dois clusters de CPU:

  • O cluster 1, o pequeno, pode gastar entre 100 e 300 mW e ter pontuações de 100 a 300 em um comparativo de mercado de throughput, dependendo dos relógios.
  • O cluster 2, o grande, pode gastar entre 1.000 e 1.600 mW e ter pontuações entre 800 e 1.200 no mesmo comparativo de mercado de throughput, dependendo dos relógios.

Nesse comparativo, uma pontuação mais alta é mais rápida. Embora não seja mais desejável do que mais lento, mais rápido == maior consumo de energia.

Se o programador acreditar que uma carga de trabalho da interface exigiria o equivalente a uma pontuação de 310 no comparativo de mercado de throughput, a melhor opção para evitar o lag é executar o cluster grande na frequência mais baixa, desperdiando energia significativa. Isso depende do comportamento de cpuidle e da corrida para o modo inativo. Os SOCs com curvas de desempenho/W contínuas são mais fáceis de otimizar.

Em segundo lugar, use cpusets. Verifique se você ativou cpusets no kernel e no BoardConfig.mk. Você também precisa configurar as atribuições cpuset reais na init.rc específica do dispositivo. Alguns fornecedores deixam essa opção desativada nos BSPs na esperança de usar outras dicas para influenciar o comportamento do programador. Achamos que isso não faz sentido. Os cpusets são úteis para garantir que o balanceamento de carga entre as CPUs seja feito de uma maneira que reflita o que o usuário está realmente fazendo no dispositivo.

O ActivityManager atribui apps a diferentes cpusets com base na importância relativa deles (superior, primeiro plano, segundo plano), com apps mais importantes tendo mais acesso aos núcleos da CPU. Isso ajuda a garantir a qualidade do serviço para apps em primeiro plano e principais.

Os cpusets são úteis em configurações de CPU homogêneas, mas não é recomendável enviar um dispositivo com uma configuração de CPU heterogênea sem cpusets ativados. O Nexus 6P é um bom modelo de como usar cpusets em configurações de CPU heterogêneas. Use isso como base para a configuração do seu dispositivo.

As cpusets também oferecem vantagens de energia, garantindo que os threads em segundo plano que não são críticos para a performance nunca sejam balanceados de carga para núcleos de CPU grandes, em que eles poderiam gastar muito mais energia sem nenhum benefício percebido pelo usuário. Isso também pode ajudar a evitar o estrangulamento térmico. Embora a limitação térmica seja um problema de capacidade, as melhorias de jitter têm um impacto enorme no desempenho da interface quando a limitação térmica é aplicada. Como o sistema vai estar mais próximo da capacidade de renderizar 60 QPS, é necessário menos jitter para causar uma queda de frame.