Scaling Governor - Gerenciando o clock da CPU no Linux - Embarcados
Como funciona o Scaling Governor?
Alterando o modo de operação da CPU
Desempenho em C
Desempenho em Go
Desempenho em Python
Você provavelmente já teve algum projeto/produto com demandas especiais para economia de energia ou desempenho extra. Focando nesses dois aspectos, vamos aprender como o Linux gerencia a frequência (clock) da CPU e também como controlá-lo, focando em maior economia, desempenho ou balanceado.
Faremos vários testes práticos para demonstrar os principais comportamentos do sistema em relação a frequência de operação da CPU. Será utilizado um Raspberry Pi Zero W para ser mais parecido com um ambiente de Linux embarcado real, mas pode ser feito nos mais diversos hardwares e distribuições, inclusive em seu computador.
Já se perguntou como o sistema operacional decide qual frequência de operação da CPU? Pode parecer uma pergunta boba, mas é um baita ponto de vista relativo. Algumas pessoas podem achar que carga acima de 10% já é motivo para aumentar a frequência, outras somente quando chegar em 70% e assim por diante.
O Kernel do Linux suporta a alteração de frequência da CPU de várias formas diferentes, sendo algumas automáticas, fixas, manuais e até dinâmicas. Todos os parâmetros e configurações estão disponíveis no sistema de arquivos (sysfs) /sys/devices/system/cpu.
Há diversos modos de operação, cada um funcionando de uma maneira que pode atender melhor o seu projeto, então vamos conhecê-los:
Performance: Mantém o clock fixo na maior frequência disponível.
Powersave: Mantém o clock fixo na menor frequência disponível.
Userspace: Libera o controle ao usuário (user space). Não efetua nenhuma ação automaticamente, é o usuário que deve alterar a frequência manualmente ou com scripts.
Schedutil: Utiliza os dados disponíveis do agendador (scheduler) da CPU para gerenciar o clock, sendo o substituto ao antigos modos "ondemand" e "conservative", por ser mais integrado a CPU e gerando menor sobrecarga no sistema.
Ondemand: Utiliza a carga da CPU para selecionar a frequência. Conta com um limite máximo (configurável) que, quando ultrapassado, eleva o clock ao máximo disponível, se não, eleva proporcionalmente à carga estimada.
Conservative: Utiliza a carga da CPU para selecionar a frequência. Similar ao "ondemand", porém, altera a frequência em pequenos passos (configuráveis), se encaixando melhor em sistemas com bateria por ser menos radical.
O modo padrão em meu Raspberry Pi Zero W é "ondemand" configurado para 50%. Já em meu desktop (Ubuntu 20.04), é "schedutil".
Vamos colocar a mão na massa e alterar o modo de funcionamento! Os comandos abaixo devem ser executados pelo usuário root. Os comandos serão mantidos até o reinício do sistema, mas se você deseja mantê-los sempre que o dispositivo reiniciar, adicione os comandos em algum lugar do boot (via rc.local, systemd e etc).
Habilitando o modo "powersave" para maior economia de energia
Habilitando o modo "performance" para maior desempenho
Habilitando o modo "ondemand" para balanceamento
Para trocar a porcentagem de carga máxima antes da frequência ser elevada ao máximo, devemos escrevê-la no arquivo "up_threshold" abaixo.
Habilitando o modo "userspace" para controle manual
Agora com o modo manual ativo, basta escrever a frequência em KHz no arquivo "scaling_setspeed" abaixo e será mantida até você trocar novamente.
Para mais detalhes e configurações dos modos, veja as referências. Também é possível alterar mais facilmente esses parâmetros utilizando o pacote "cpufrequtils", que expõe esses comandos de forma amigável.
Com o propósito de demonstrar alguns comportamentos e métricas importantes ao desenvolvimento de projetos e produtos, foram efetuados diversos testes em diferentes frequências da CPU no Raspberry Pi Zero W. Assim, conseguimos saber se é uma boa ideia alterar a frequência da CPU em nosso projeto para melhorar consumo, desempenho e etc.
Figura 1: Teste de Temperatura vs Frequência.
Relação entre os extremos:
Frequência: Aumento de 42.86%.
Temperatura: Aumento de 8.7%.
Raspberry sem qualquer tipo de dissipação e em stress de CPU. Temperatura ambiente: 24°C.
Figura 2: Teste de Consumo vs Frequência.
Consumo: Aumento de 21,95%.
Figura 3: Teste de desempenho, C vs Frequência.
Desempenho: Aumento de 44.24%.
Figura 4: Teste de desempenho, Go vs Frequência.
Desempenho: Aumento de 44.81%.
Figura 5: Teste de desempenho, Python vs Frequência.
Desempenho: Aumento de 43.32%.
Desempenho geral lado a lado
Figura 6: Desempenho geral.
As 3 linguagens testadas se beneficiaram igualmente com o aumento da frequência, confirmando a importância de sempre estarmos atentos a frequência da CPU, tanto para um rápido processamento ou até consumo energético. Você deve estudar o melhor caso e aplicar de acordo com a demanda do seu projeto, balanceando quando necessário!
O algoritmo utilizado para teste de desempenho nas linguagens foi o cálculo da quantidade de números primos existentes até 20000. Não foi utilizado nenhum parâmetro de otimização de compilador e nem otimizações específicas da linguagem, sendo um algoritmo simples para ser o mais parecido possível em todas as linguagens. O foco do teste é observar se as linguagens ganham o mesmo aumento de desempenho e não sobre qual é mais rápida.
O algoritmo e todos dados dos gráficos acima podem ser visualizados no repositório do github: https://github.com/urbanze/linux_scaling_governor
https://www.kernel.org/doc/html/v5.10/admin-guide/pm/cpufreq.html
Home » Linux Embarcado » Scaling Governor – Gerenciando o clock da CPU no Linux
Excelente artigo. Muito além da teoria. Informações importantes e que muitas vezes são relegadas nos projetos.