segunda-feira, 22 de novembro de 2010

Optimizações para o arranque (e não só)

Ultimamente tenho estado a testar técnicas de melhoria de desempenho no meu computador.

# apt-get install readahead-fedora preload
# #switch apt repositories to unstable, apt-get update
# apt-get install bootchart bootchart-view
# #switch apt repositories back to testing

Com a utilização do readahead consegue-se reduzir o tempo de arranque da máquina. No meu PC, reduzi de cerca de 66 segundos para 55. O Ubuntu utiliza o ureadahead, uma variante deste programa.
Com o preload, o tempo de espera antes de os programas iniciarem reduz-se visivelmente.
O tempo de arranque é medido com o bootchart. É contabilizado desde o momento em que o kernel é carregado pelo GRUB até depois de o preload ter terminado. O desktop pode ser utilizado um pouco antes de o preload iniciar, algo que deve ser bem evidente no gráfico.

AVISO: As instruções a seguir devem ser vistas como indicações e não como um how to pronto a seguir. Para se obterem os melhores resultados os passos devem ser afinados para a configuração de cada máquina.

bootchart:
Cria um gráfico de utilização do CPU, acessos a disco e de processos em execução. É bastante útil para analisar o processo de arranque. Não está em Debian testing, pelo que é necessário trocar temporariamente os repositórios para unstable para o instalar.
  1. Activar o bootchart:
    $ grep CMDLINE /etc/default/grub
    GRUB_CMDLINE_LINUX_DEFAULT="quiet init=/sbin/bootchartd"

  2. Ver o dito gráfico:
    $ cd /tmp/; bootchart; eog bootchart.png

  3. Convém fazer com que o bootchart registe *todo* o processo de arranque. Com a configuração pré-definida em Debian só é registado o arranque até todos os programas terem sido iniciados. Como nesse momento o sistema ainda não está pronto a utilizar, convém esperar mais um pouco (cerca de 20 segundos, no meu caso).
    Depois de todas as alterações neste post, o último processo a considerar como parte do arranque passará a ser o preload. O bootchart só deve terminar então depois de o preload ter terminado. Antes da configuração do preload, e para melhor compreender as configurações intermédias, pode-se considerar o gvfsd-metadata (ver adiante).

    Terminar o bootchart 30 segundos depois de o preload iniciar a execução:
    $ cat /etc/init.d/bootchart
    (...)
    case "$1" in
    start)
    RETSTATUS=1
    while [ ! $RETSTATUS -eq 0 ] ; do
    #this is inside an if because otherwise the script fails and dies...
    if /bin/sh -c "/bin/pidof /usr/sbin/preload > /dev/null"; then
    RETSTATUS=$?
    else
    RETSTATUS=$?
    fi
    sleep 1;
    done
    sleep 30;
    if pgrep -x $NAME > /dev/null; then
    (...)

Depois destas configurações é necessário executar:
# update-grub


readahead:
É composto por três tarefas essenciais:
  1. Profiling - analisa o processo de arranque da máquina e guarda um registo dos ficheiros necessários durante o mesmo. Esta operação é executada pelo menos uma vez por mês ou sempre que o processo sofre alterações (p.ex., com a instalação ou actualização de pacotes). Quando isto acontece, o processo é mais lento do que o habitual (no meu caso, o pior que vi foi 20 segundos mais lento -- depois das optimizações aqui indicadas, o profiling passa a pesar apenas uns 2 a 5 segundos adicionais);

  2. readahead - sempre que o sistema inicia, e antes de qualquer outra operação, lê os ficheiros que vão ser necessários do disco para memória, de forma sequencial e contínua;

  3. Optimização - diariamente, enquanto a máquina está a ser utilizada, o registo de ficheiros a ler é ordenado para que a leitura do disco durante o arranque seja ainda mais rápida.

A configuração que se segue faz com que o profiling seja feito durante *todo* o processo de arranque, desde o início até ao momento em que o desktop está pronto a ser utilizado.
No meu PC, decidi que esse instante é o momento em que o processo gvfsd-metadata já se encontra em execução. Digo ainda ao profiler para se manter em execução durante 3 segundos depois de detectar este processo.

Estas configurações foram determinadas empiricamente, através da observação do gráfico do bootchart. O gvfsd-metadata é o último processo que vejo a iniciar no gráfico. Isto poderá mudar em futuras versões do Gnome, para além de que outras configurações podem fazer com que seja outro processo qualquer o último a iniciar. Convém escolher sempre o "último" processo mais adequado para a máquina em questão.

$ grep COLLECT /etc/default/readahead-fedora 
READAHEAD_COLLECT="yes"
READAHEAD_EXTRA_COLLECT="3"

$ cat /etc/init.d/stop-readahead-fedora
(...)
case "$1" in
start|stop)
(
RETSTATUS=1
while [ ! $RETSTATUS -eq 0 ] ; do
if /bin/sh -c "/bin/pidof gvfsd-metadata > /dev/null"; then
RETSTATUS=$?
else
RETSTATUS=$?
fi
sleep 1;
done

rm -f /.readahead_collect
(...)


Se existirem ficheiros de configuração em /etc/readahead.d/, pode ser conveniente apagá-los antes do primeiro profiling ou depois da afinação destes parâmetros.

O ficheiro /etc/readahead.conf tem parâmetros interessantes que podem (e devem) ser afinados (ver RAC_EXCLUDE).


Depois desta configuração é necessário executar:
# touch /.readahead_collect
...para que o profiler corra no próximo arranque.

preload:
Este programa está permanentemente em execução e analisa os padrões de utilização do computador por parte do utilizador. Tendo em conta esta análise, faz uma previsão das bibliotecas e executáveis que deverão ser pedidos brevemente e lê-os do disco para a memória antes de serem necessários.

AVISO: É importante que o preload nunca comece a executar ao mesmo tempo que o readahead está em profiling. Com a configuração anterior o profiler do readahead irá terminar 4 segundos depois de o gvfsd-metadata iniciar. A modificação ao script de inicialização em baixo faz com que o preload inicie 10 segundos depois de o mesmo processo iniciar, evitando que profiler e preload executem em concorrência.
No meu computador isto é suficiente. Noutros pode não ser. Mais uma vez, é essencial observar os gráficos do bootchart para tomar uma "boa" decisão.

Ao fim de alguns dias de utilização começam a notar-se melhorias na velocidade do sistema. :)

$ cat /etc/init.d/preload
(...)
# Required-Start: $all
(...)
start)
echo -n "Starting $DESC: "
RETSTATUS=1
while [ ! $RETSTATUS -eq 0 ] ; do
if /bin/sh -c "/bin/pidof gvfsd-metadata > /dev/null"; then
RETSTATUS=$?
else
RETSTATUS=$?
fi
sleep 1;
done
sleep 10;
if start-stop-daemon --start --quiet -u 0 $PRELOAD_IOSCHED --exec $DAEMON -- $DAEMON_OPTS; then
(...)


O ficheiro /etc/preload.conf tem parâmetros que podem (e devem) ser afinados (ver mapprefix e exeprefix).

Depois desta configuração é necessário executar:
# update-rc.d preload disable
# update-rc.d preload enable



Referências:
Bootchart
README e ficheiros de configuração do readahead e preload (/usr/share/doc/{readahead-fedora,preload}/, /etc/{readahad,preload}.conf)

Sem comentários: