Gerenciamento de Frequência do Notebook
Índice
- 1. Sumário
- 2. 1 Requisitos
- 3. 2 A documentação do kernel Linux
- 4. 3 Interface para controle de frequência
- 5. 4 Modos padrões de controle de frequência da CPU (CPUFreq Governor)
- 5.1. 4.1 Performance
- 5.2. 4.2 Powersave
- 5.3. 4.3 Userspace
- 5.4. 4.4 Ondemand
- 5.5. 4.5 Conservative
- 6. 5 O problema
- 7. 6 A solução
- 7.1. 6.1 As funções
- 7.1.1. 6.1.1 cpu_governor
- 7.1.2. 6.1.2 get_cpu_avaliable_freqs
- 7.1.3. 6.1.3 cpu_freq
- 7.1.4. 6.1.4 get_temp
- 7.1.5. 6.1.5 Considerações finais sobre as funções
- 7.2. 6.2 O corpo do script
- 8. 7 Conclusão
- 9. About this document …
Aproveitando o período de férias experimentei compilar os quase 1GB de pacotes do Gnome. O processo foi bem demorado, colocando o notebook em alta atividade com a temperatura beirando os 70°C. Sempre que observava temperaturas desta ordem reduzia, manualmente, a frequência da CPU. Depois de algumas horas de compilação resolvi criar um Script Shell para automatizar o controle.
Neste texto vou apresentar como implementar um Gerenciador de Frequência da CPU Personalizado, com simples comando de leitura e escrita pelo Shell.
Todas as informações necessárias para este trabalho foram obtidas na documentação do Kernel Linux.
Sumário
- 1 Requisitos
- 2 A documentação do kernel Linux
- 3 Interface para controle de freqüência
- 4 Modos padrões de controle de freqüência da CPU (CPUFreq Governor)
- 5 O problema
- 6 A solução
- 7 Conclusão
1 Requisitos
Antes de começar, alguns requisitos devem ser observados. Se você é um daqueles que gosta de customizar seu kernel, não se esqueça de adicionar suporte ao controle de temperatura pela ACPI e ao Gerenciador de Frequência da CPU:
Power management options --->
ACPI (Advanced Configuration and Power Interface) Support
[*] ACPI Support
[*] Sleep States
<M> Processor
<M> Thermal Zone
CPU Frequency scaling --->
[*] CPU Frequency scaling
<M> CPU frequency translation statistics
[*] CPU frequency translation statistics details
Default CPUFreq governor (performance) --->
--- 'performance' governor
<M> 'powersave' governor
<M> 'userspace' governor for userspace frequency scaling
<M> 'ondemand' cpufreq policy governor
<M> 'conservative' cpufreq governor
<M> AMD Opteron/Athlon64 PowerNow!
<M> Intel Enhanced SpeedStep (deprecated)
<M> ACPI Processor P-States driver
A primeira parte da configuração, ACPI Support, é necessária para o monitoramento da temperatura, o segundo bloco, Power management options, é quem adiciona o gerenciamento de frequência da CPU. As três últimas seleções dependem de sua CPU, veja mais detalhes abaixo.
Caso esteja usando o kernel padrão, acredito que estes módulos devem estar disponíveis. Para tudo funcionar, é necessário carregar os seguintes módulos durante a inicialização do sistema:
- cpufreq_stats;
- freq_table;
- powernow_k8 (dependendo do seu processador);
- speedstep_centrino (dependendo do seu processador);
- acpi_cpufreq (dependendo do seu processador);
- cpufreq_userspace;
- cpufreq_conservative;
- cpufreq_ondemand;
- cpufreq_powersave;
- cpufreq_performance;
- thermal (para o monitoramento da temperatura);
Observe que na configuração do kernel, incorporei o modo cpufreq_performance ao kernel como o CPUFreq governor padrão. Por este motivo este módulo não deverá existir como módulo disponível para carga. Algo parecido deve acontecer com o kernel padrão de sua distribuição.
Antes de prosseguir, carregue os módulos:
LIST="cpufreq_stats freq_table powernow_k8 cpufreq_userspace cpufreq_conservative cpufreq_ondemand cpufreq_powersave cpufreq_performance thermal" [prompt]for MOD in $LIST; do modprobe $MOD; done
Para uma CPU Intel Pentium M (Centrino) ou 64bit Intel Xeon, carregue o módulo speedstep_centrino e para outras CPUs Intel use o módulo acpi_cpufreq, no lugar do módulo powernow_k8. O módulo speedstep_centrino está sento substituído pelo módulo acpi_cpufreq, por isto é aconselhável usar este último na maioria das CPUs Intel.
2 A documentação do kernel Linux
Na ocasião usei o kernel 2.6.22.8 que veio nativo em meu Slamd64 12.0. A documentação desejada se encontra na pasta /usr/src/linux/Documentation/cpu-freq.
Nesta pasta existe um arquivo de índice, index.txt, que traz algumas informações sobre os documentos disponíveis neste diretório. Os documentos que irei utilizar neste texto são:
- governors.txt
- informações sobre os modos de gerenciamento de frequência e informações para sua implementação;
- cpufreq-stats.txt
- que traz informações sobre tempos de transação, número de transações, …;
- user-guide.txt
- um guia rápido que traz informações sobre onde e como alterar as configurações do gerenciador de frequência da CPU.
Existe outros textos interessantes nesta pasta com informações para criar drivers específicos para outras CPUs, listas de informações dos desenvolvedores e outros links de interesse.
3 Interface para controle de frequência
As interfaces para o controle de frequência da CPU estão localizados no sistema de arquivos sysfs, geralmente montado na raiz do sistema em /sys. Em /sys/devices/system/cpu/cpu0/cpufreq/, para a primeira CPU, são encontrados vários arquivos com informações importantes para o controle de frequência. Dependendo de sua CPU, são disponíveis os arquivos de controle:
- cpuinfo_min_freq
- (somente leitura) frequência mínima suportada pela CPU;
- cpuinfo_max_freq
- (somente leitura) frequência máxima suportada pela CPU;
- cpuinfo_cur_freq
- (somente leitura) frequência atual da CPU;
- scaling_available_frequencies
- (somente leitura) frequência suportadas pela CPU. No caso de meu Athlon(tm) 64 Processor 3200+, são suportadas as frequências: 1,0GHz, 1,8GHz, e 2,0GHz. Faça um
cat
neste arquivo para conhecer as frequências suportadas por sua CPU; - scaling_available_governors
- (somente leitura) modos de operação suportados pela CPU. Os modos reconhecidos pelo kernel Linux são: userspace, conservative, ondemand, powersave e performance;
- scaling_cur_freq
- (somente leitura) o mesmo que cpuinfo_cur_freq;
- scaling_driver
- (somente leitura) o driver utilizado pelo gerenciador de frequência. Em minha máquina o driver é powernow-k8;
- scaling_governor
- (leitura/escrita) seleciona o modo do gerenciador de frequência da CPU. Para alterar o modo de operação do controle de frequência da CPU, basta imprimir neste arquivo um dos modos, contidos em scaling_available_governors, suportados por sua CPU;
- scaling_max_freq
- (leitura/escrita) geralmente possui o mesmo valor que cpuinfo_max_freq, porem pode ter seu conteúdo alterado;
- scaling_min_freq
- (leitura/escrita) geralmente possui o mesmo valor que cpuinfo_min_freq, porem pode ter seu conteúdo alterado;
- scaling_setspeed
- (leitura/escrita) geralmente possui o mesmo valor que cpuinfo_cur_freq. Este arquivo permite selecionar uma das frequências contidas em scaling_available_frequencies, para a operação da CPU. Observe que este arquivo estará presente somente quando o modo do gerenciador selecionado for userspace.
Para saber quais arquivos aceitam escrita, além da leitura, basta olhar as permissões com algo como o comando ls
:
ls -la /sys/devices/system/cpu/cpu0/cpufreq/ total 0 drwxr-xr-x 4 root root 0 2009-07-28 10:31 ./ drwxr-xr-x 7 root root 0 2009-07-28 09:30 ../ -r--r--r-- 1 root root 4096 2009-07-28 09:30 affected_cpus -r-------- 1 root root 4096 2009-07-28 11:39 cpuinfo_cur_freq -r--r--r-- 1 root root 4096 2009-07-28 11:39 cpuinfo_max_freq -r--r--r-- 1 root root 4096 2009-07-28 11:39 cpuinfo_min_freq drwxr-xr-x 2 root root 0 2009-07-28 10:31 ondemand/ -r--r--r-- 1 root root 4096 2009-07-28 11:39 related_cpus -r--r--r-- 1 root root 4096 2009-07-28 09:31 scaling_available_frequencies -r--r--r-- 1 root root 4096 2009-07-28 09:30 scaling_available_governors -r--r--r-- 1 root root 4096 2009-07-28 09:31 scaling_cur_freq -r--r--r-- 1 root root 4096 2009-07-28 09:31 scaling_driver -rw-r--r-- 1 root root 4096 2009-07-28 10:31 scaling_governor -rw-r--r-- 1 root root 4096 2009-07-28 11:39 scaling_max_freq -rw-r--r-- 1 root root 4096 2009-07-28 11:39 scaling_min_freq -rw-r--r-- 1 root root 4096 2009-07-28 11:39 scaling_setspeed drwxr-xr-x 2 root root 0 2009-07-28 11:39 stats/
4 Modos padrões de controle de frequência da CPU (CPUFreq Governor)
Como visto acima, em scaling_available_governors, existem cinco modos de controle de frequência da CPU suportadas pelo kernel Linux atualmente. Abaixo faço uma breve descrição destes modos.
4.1 Performance
Como o nome já diz, performance deixa a CPU na mais alta frequência de operação, scaling_max_freq, ou seja, mais desempenho na compilação e execução dos aplicativos e também maior aquecimento do processador. Este modo de operação do gerenciador de frequência é o modo padrão na maioria dos kernels distribuídos.
4.2 Powersave
O modo powersave, coloca a CPU no modo de economia de energia, o que resulta em menor frequência de operação, scaling_min_freq, menor desempenho na compilação e execução dos aplicativos e, consequentemente, menor temperatura de operação da CPU. Geralmente é o modo padrão para uso do Notebook, quando este está ligado apenas à bateria.
4.3 Userspace
Userspace é um modo de operação do gerenciador de frequência de interesse nesse texto. Ele permite ao administrador do sistema, root, selecionar uma frequência específica para a operação da CPU. Esta seleção de frequência é feita escrevendo o valor da frequência desejada no sysfs scaling_setspeed.
4.4 Ondemand
No modo ondemand, a frequência da CPU será selecionada de acordo com a demanda por processamento solicitada pelo sistema. Na prática, o gerenciador de frequência da CPU configura a frequência de operação para o máximo, scaling_max_freq, quando o consumo de processamento da CPU atinge 80%, e para o mínimo, scaling_min_freq, quando a solicitação de processamento for baixa.
4.5 Conservative
O modo conservative é bem parecido ao modo ondemand. A maior diferença entre estes modos de gerenciamento, está na forma como as mudanças na frequência de operação da CPU é feita. Ao invés de chavear entre a frequência máxima e mínima, como no modo ondemand, as mudanças de frequência são feitas de forma mais suave e lenta. Mais detalhes sobre estes critérios podem ser encontradas na documentação especificada anteriormente.
5 O problema
A necessidade na ocasião que me levou a criar este texto, era manter o Notebook compilando os pacotes do Gnome, entre outras condições adversas, sem que isto levasse o processador a um aquecimento indesejado. Portanto, o controle de frequência será regido pela temperatura da CPU e não pela demanda por processamento.
O objetivo é manter a temperatura de operação da CPU abaixo dos 55°C, baixando a frequência de operação da até que a meta seja alcançada ou se atinja a frequência mais baixa de operação da CPU.
6 A solução
Está é uma solução simples para o problema e é claro que pode ser adicionado outras habilidades mais inteligentes ao gerenciador de frequência, mas isto ficará para uma segunda implementação.
#!/bin/bash
#
# Controle de Frequência da CPU pela temperatura
# Por Rudson R. Alves
# v 1.0
#
function cpu_governor {
# Função para escrever o modo de operação do CPUFreq Governor
if [ $# -eq 0 ]; then
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
else
echo $1 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
fi
}
function get_cpu_avaliable_freqs {
# Ler frequências de operação da CPU
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
}
function cpu_freq {
# Seleciona/Le a freqüência da CPU
if [ $# -eq 0 ]; then
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq | cut -c1-4
else
echo $1 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
fi
}
function get_temp {
# Pega a temperatura da CPU
cat /proc/acpi/thermal_zone/THRM/temperature | awk '{ print $2 }'
}
# ---- Script ----
MAX_TEMP=${MAX_TEMP:=55}
MIN_TEMP=${MIN_TEMP:=45}
SLEEP=${SLEEP:=10}
PROGRAM_NAME=`basename $0 | tr 'a-z' 'A-Z'`
# Carrega as freqs de operação da CPU
N=0
for f in `get_cpu_avaliable_freqs`; do
FREQ[N]=$f
let N++
done
let N--
MAX_F=$N
# Coloca o controle de freq em Userspace
cpu_governor "userspace"
# Coloca a freq no valor máximo
cpu_freq ${FREQ[N]}
clear
echo "$PROGRAM_NAME v-1.0"
echo -e "\033[1;1H"
echo -e "Temperature Min: ${MIN_TEMP}°C \033[30G Max: ${MAX_TEMP}°C"
echo -e "CPUFreq Governor: $( cpu_governor )"
echo -e "Refresh time: ${SLEEP}s\n"
while [ 1 -ne 2 ]; do
TEMP=`get_temp
if [ $TEMP -ge $MAX_TEMP ]; then
if [ $N -gt 0 ]; then
let N--
cpu_freq ${FREQ[N]}
fi
elif [ $TEMP -le $MIN_TEMP ]; then
if [ $N -lt $MAX_F ]; then
let N++
cpu_freq ${FREQ[N]}
fi
fi
COLUMNS=`tput cols`
CPU_CLOCK=`cpu_freq`
echo -e "\033[6;1HCPU Freq: ${CPU_CLOCK} MHz Temp: ${TEMP}°C"
echo -e "\nUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND"
ps aux | awk '{ if ( $3 >= 1 ) print $0 }' | cut -c-$(( COLUMNS - 1 ))
sleep $SLEEP
echo -e "\033[9;1H\033[0J"
done
O script está um pouco enfeitado, mas seu funcionamento é bem simples. Farei alguns comentários pertinentes às funcionalidades apresentadas no texto. Detalhes sobre o bash ou os comandos do shell não serão o foco aqui.
6.1 As funções
O gerenciamento da frequência é feito pelas funções cpu_governor
(linha 7) e cpu_freq
(linha 23). A escolha do modo de operação do gerenciador de frequência é feita escrevendo o modo desejado no sysfs scaling_governor com um comendo echo
. Vou fazer uma avaliação rápida destas funções, a seguir.
6.1.1 cpu_governor
A função cpu_governor
permite ler o modo de operação do gerenciador de frequência, quanto chamada sem argumento, fazendo um cat
no sysfs scaling_governor, linha 11. Quando um argumento é passado, o seu valor é enviado para o mesmo sysfs scaling_governor, por um comando echo
, linha 13.
6.1.2 get_cpu_avaliable_freqs
Esta função pega as frequências de operação suportadas pela CPU, consultando o sysfs scaling_available_frequencies, com um comando cat
, linha 20.
6.1.3 cpu_freq
Assim como a função cpu_governor, esta função serve para a entrada da frequência de operação da CPU e para a leitura desta frequência. Se não for passado nenhum argumento para a função, a frequência atual será lida consultando o sysfs cpuinfo_cur_freq, com o comando cat
na linha 27.
Se for passado um argumento, ele será entendido como um frequência suportada pela CPU, escrevendo seu valor no sysfs scaling_setspeed, linha 26.
A leitura da frequência de operação da CPU poderia ter sido feita no sysfs scaling_setspeed, assim como é feito na escrita. A escolha em não fazê-lo, se deve a não existência deste sysfs, até que o modo de operação da CPU seja mudado para userspace. Esta atitude garante que a função funcionará independentemente do modo de operação do gerenciador de frequência.
6.1.4 get_temp
A leitura da temperatura é feita consultando o sistema de arquivo virtual /proc
, na linha 36. O comando awk
ao final da linha serve para isolar apenas o valor numérico da temperatura da CPU.
6.1.5 Considerações finais sobre as funções
Observe que não foi feito nenhum tratamento de erro nestas funções. Por isto os valores passados às funções devem ser suportados por sua CPU. Na CPU testada, valores não suportados foram ignorados, mas não posso garantir o mesmo comportamento ocorra em outras CPUs. Para o funcionamento deste script, é necessário o suporte ao modo de gerenciamento de frequência userspace, pela CPU.
6.2 O corpo do script
O script inicia com a criação de três variáveis de controle:
- MAX_TEMP
- com a máxima temperatura de ação. Sempre que a temperatura da CPU for superior ou igual a este valor, a frequência da CPU será reduzida. O valor padrão é 55°C;
- MIN_TEMP
- com a temperatura mínima de ação. Sempre que a temperatura da CPU for inferior ou igual a este valor, a frequência da CPU será aumentada. O valor padrão é 45°C;
- SLEEP
- é o tempo entre uma leitura e outra da temperatura da CPU, em segundos. O Valor padrão é 10s.
Estas definições são feitas nas linhas 40, 41 e 42.
Em seguida o script carrega as frequências suportadas pela CPU e as armazena no vetor FREQ[]
, nas linhas 45 à 52. A variável MAX_F
armazena o índice da maior frequência e N
será o índice para a frequência selecionada durante a execução do programa.
Depois, o gerenciador de frequência é colocado no modo userspace, linha 55, e a frequência da CPU é alterada para o valor máximo, linha 57.
A linha 66 inicia um loop infinito, onde a frequência é monitorada e selecionada de acordo com a temperatura.
Inicialmente a temperatura é lida na linha 67, e depois comparada com a MAX_TEMP
, linha 69. Caso a temperatura seja maior que a MAX_TEMP
, e frequência será reduzida, caso não tenha alcançado o seu valor mínimo, linhas 70 à 73.
Caso a temperatura seja menor que MIN_TEMP
, linha 74, a frequência será aumentada, caso não tenha alcançada o seu valor máximo, linhas 75 à 78.
O restante do script é para gerar as informações apresentadas enquanto o gerenciador de frequência está em funcionamento, como os parâmetros de operação do scripts, temperatura, frequência, processos com consumo de CPU acima de 1%, …
O quadro abaixo apresenta o script sendo executado em minha máquina, enquanto o VirtualBox executa um Slackware 12.0, compilando o Gnome.
GOVERNOR_CPU v-1.0
Temperature Min: 45°C Max: 55°C
CPUFreq Governor: userspace
Refresh time: 10s
CPU Freq: 1800 MHz Temp: 51°C
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2405 1.8 7.6 159184 73240 tty7 Ss+ 13:45 8:01 /usr/bin/X -br
rudson 2743 50.6 43.2 617916 415688 ? Sl 13:49 216:39 /opt/VirtualBo
root 29506 73.6 0.9 16728 9292 ? R 18:13 120:11 scripts/kconfi
7 Conclusão
Algumas implementações interessantes como o uso do modo ondemand ou conservative, controlando os limites máximo e mínimo da frequência de operação da CPU, através dos sysfs scaling_max_freq e scaling_min_freq, ou mesmo um controle total do comportamento do gerenciador de frequência, para incluir a demanda por processamento, ficam a encargo do leitor.
No meu modo de ver, este texto é apenas uma pequena demonstração da diversidade de conhecimentos disponível para se envolver neste mundo de possibilidades que é o Software Livre. Espero ter dado minha pequena contribuição para despertar a curiosidade para estas muitas possibilidades.
About this document …
Gerenciamento de Frequência em um Notebook
This document was generated using the LaTeX2HTML translator Version 2002-2-1 (1.71)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -split 0 -nonavigation -show_section_numbers cpu_freq-2.tex
The translation was initiated by on 2008-02-17
2008-02-17
2 Comentários