Usando cgroups do Linux para equilibrar o desempenho da CPU

12

Eu tenho dois sistemas Linux dual-core instalados usando cgroups do Linux com kernels relativamente recentes; um está executando Debian Squeeze, o outro Ubuntu 11.04 Natty Narwhal. Eu obtive balanceamento de carga da CPU com cgroups trabalhando um pouco melhor no sistema Debian apesar de seu kernel antigo. Mas não é certo para tudo, e a peculiaridade específica que estou perguntando aqui acontece em ambos os sistemas.

Se você ler Gerenciamento de recursos no Linux com grupos de controle dá um exemplo mostrando como reproduzir o problema. Aqui está a versão do Ubuntu (rode isso como root):

cd /sys/fs/cgroup/cpu
    [On Debian Squeeze start at /mnt/cgroups/cpu instead]
mkdir low high
echo 512 > low/cpu.shares
echo 2048 > high/cpu.shares
yes low > /dev/null &
echo $! > low/tasks
yes high > /dev/null &
echo $! > high/tasks
ps -C yes -opid,%cpu,psr,args
    [repeat that a few times]
killall -9 yes

Eu esperava que o processo "alto" fosse alocado mais tempo que o "baixo"; o que realmente acontece com este caso de teste é sempre mais assim:

root@black:/sys/fs/cgroup/cpu# ps -C yes -opid,%cpu,psr,args
  PID %CPU PSR COMMAND
 3105 88.3   1 yes low
 3106 94.5   0 yes high

Onde os tempos são quase iguais. Aqui está a minha pergunta: por que isso está acontecendo?

Na apresentação, esse problema é mostrado indo fixando cada processo na mesma CPU; linhas adicionais para testar isso:

taskset -c 1 yes high > /dev/null &
echo $! > high/tasks
taskset -c 1 yes low > /dev/null &
echo $! > low/tasks
ps -C yes -opid,%cpu,psr,args
[later, rinse, repeat]
killall -9 yes

O resultado é o que eu esperava ver o tempo todo: o processo "alto" fica com uma porcentagem muito maior da CPU:

root@black:/sys/fs/cgroup/cpu# ps -C yes -opid,%cpu,psr,args
  PID %CPU PSR COMMAND
 3128 83.3   1 yes high
 3129 20.7   1 yes low

Explicar por que isso funciona seria um passo útil para descobrir por que o anterior também não funciona.

    
por Greg Smith 11.10.2011 / 08:23

1 resposta

10

Eu recebi uma explicação inicial sobre este caso de teste de Stefan Seyfried, que escreveu o artigo do qual este exemplo foi retirado. O problema aqui é que as partes do cgroups do planejador de CPU sempre visam manter qualquer CPU disponível ocupada; ele nunca aplica um limite rígido se tudo se encaixar de uma só vez.

No caso em que dois processos (alto e baixo aqui) estão sendo executados em > = 2 núcleos, ele continuará alto em um núcleo e baixo em outro. Ambos serão executados o tempo todo, com cerca de 100% de uso, porque podem fazê-lo sem atingir a situação em que o agendador não lhes dá tempo suficiente na CPU. O agendamento do cpu.share só acontece se houver uma falta.

No segundo caso, ambos os processos são fixados na mesma CPU. Em seguida, a lógica de compartilhamento da CPU precisa fazer algo útil com os números relativos de cpu.shares para equilibrá-los, e faz isso como esperado.

Os limites rígidos de uso da CPU provavelmente não aparecerão até depois do patch do Controle de Largura de Banda CFS ser atingido. Nesse ponto, pode ser possível obter algo mais parecido com o que eu esperava.

    
por 11.10.2011 / 13:28