linux-5.1/Documentation/cpu-load.txt
[...]
Na maioria dos casos, as
/proc/stat
informações refletem a realidade de forma bastante próxima, no entanto, devido à natureza de como/quando o kernel coleta esses dados, às vezes não pode ser confiável.[...]
Se imaginarmos o sistema com uma tarefa que periodicamente queima ciclos da seguinte maneira:
time line between two timer interrupts |--------------------------------------| ^ ^ |_ something begins working | |_ something goes to sleep (only to be awaken quite soon)
Na situação acima o sistema estará 0% carregado de acordo com o
/proc/stat
(já que a interrupção do timer sempre acontecerá quando o sistema estiver executando o handler inativo), mas na realidade a carga está próxima de 99%.
Este documento foi adicionado em 2007.
Por exemplo, o escalonador da CPU (por exemplo, função schedule()) foi modificado para medir o tempo toda vez que um processo transita de executável para em espera, se houver uma fonte de tempo suficientemente barata e confiável ( TSC confiável )?
O documento inclui um programa de exemplo, smallhog.c
. De acordo com o encadeamento vinculado no LKML.org, ele conseguiu monopolizar a CPU, e o kernel relatou apenas alguns % de uso da CPU ou menos.
Eu tentei compilar e executá-lo no meu sistema atual. O kernel relatou o uso da CPU do programa como cerca de 80%. Assim, a situação parece ter mudado um pouco. Sabemos exatamente por que smallhog.c
é menos eficaz neste sistema?
Eu uso o Fedora 30, kernel Linux v5.2.0-rc5 (aproximadamente), rodando no modo de 64 bits em "CPU Intel(R) Core(TM) i5-5300U".
lscpu
mostraconstant_tsc
enonstop_tsc
.journalctl -k | grep -iE "TSC|clocksource"
parece que o kernel não encontra nenhum problema com o TSC.cat /sys/devices/system/clocksource/clocksource0
mostra "tsc".
Eu vejo que o tópico vinculado diz
Isso não é verdade em todas as arquiteturas, algumas fazem uma contabilidade mais precisa registrando os tempos nas transições de usuário/kernel/interrupção...De fato. É certamente a maneira como as arquiteturas comuns de PC mais chatas fazem isso.
(Talvez os desenvolvimentos do hrtick possam afetar esse problema? Mesmo que apenas para torná-lo mais difícil de explorar. Ou mais fácil? Ou apenas exigir um código ligeiramente diferente para explorar?).
Você disse que o
smallhog
processo mostra 80% do tempo de CPU. Os 20% restantes do tempo nessa CPU são contabilizados como interrupções! Por que o smallhog.c mostra menos de 100% de uso da CPU no meu sistema?smallhog
está fazendo algo com muita interrupção. Sua tática específica é claramente derrotada porIRQ_TIME_ACCOUNTING
. Veja abaixo.Eu suspeito que ainda há uma maneira de evitar o tique-taque do temporizador :-). Você provavelmente precisa de uma maneira inteligente de prever quando o carrapato será acionado. Por exemplo, olhando para
/proc/interrupts
.Este recurso está habilitado nas configurações do kernel do Fedora (veja
/boot/config-*
). Em CPUs x86, ele usa o TSC. O recurso pode ser desabilitado com uma opção de inicialização,tsc=noirqtime
.[*]Métodos contábeis mais precisos
Conforme mencionado na pergunta, o PowerPC / S390 possui um código específico que pode contabilizar o tempo de CPU em cada switch de contexto. Isso é chamado
VIRT_CPU_ACCOUNTING_NATIVE
. Mas seu kernel x86 não tem isso.Existe um equivalente genérico, chamado
VIRT_CPU_ACCOUNTING_GEN
. (GEN é a abreviação de "genérico"). Este recurso está embutido no kernel do Fedora. Mas esse recurso não é ativado por padrão.Você tem que ler com atenção :-).
VIRT_CPU_ACCOUNTING_GEN
só se torna ativo em "sistemas full dynticks". Embora a configuração do kernel do Fedora incluaNO_HZ_FULL
, o Fedora não habilita "dynticks completos" por padrão. Habilitar "full dynticks" requer a especificação de uma opção no momento da inicialização,nohz_full=
, com uma lista de "CPUs adaptáveis". ("Pelo menos uma CPU não adaptável deve permanecer online...")Veja linux-5.2-rc5/init/Kconfig :
Marquei uma linha no último parágrafo porque está desatualizado. "O subsistema full dynticks" já foi desenvolvido.
[*] Considerações TSC
Se uma CPU x86 não tiver um TSC, o kernel não tentará usar nenhuma outra fonte de clock de hardware para
IRQ_TIME_ACCOUNTING
(ou paraVIRT_CPU_ACCOUNTING_GEN
).O código sugere que qualquer TSC disponível é aceito. Eu não sei como isso funciona com CPUs que não possuem
constant_tsc
:-). Embora eu tenha 99,9% de certeza de que os mantenedores relevantes estavam cientes desse problema e teriam perguntado por que era aceitável.Veja native_sched_clock() e tsc_init() :