cpu time measurement com wait4 vs. cpuacct cgroup

3

Eu quero iniciar um processo e medir o tempo da CPU (user + sys) de que precisa até que termine.

Eu sei que posso usar a chamada de sistema wait4 , que retorna uma estrutura com o usuário e a hora do sistema (eu uso a soma de ambas as vezes).

Eu também posso usar o cpuacct cgroup subsystem , colocar o processo em um novo cgroup e leia o arquivo cpuacct.usage (que contém o tempo combinado do usuário e do sistema).

Eu sei que o primeiro tem problemas quando o processo gera subprocessos (às vezes seu tempo não é contado). No entanto, pensei que, para um caso de processo único, as duas medições deveriam ser quase iguais. Eu esperava que o valor cpuacct fosse um pouco menor, porque eu só posso colocar o processo no cgroup depois que ele foi criado (mas eu faço isso imediatamente após o fork, então a diferença deve ser mínima).

Agora, para processos que demoram alguns segundos, vejo os resultados esperados.

Exemplos:

wait4:   8.292518s
cpuacct: 8.299105444s

wait4:   13.788861s
cpuacct: 13.796484557s

wait4:   24.229514s
cpuacct: 24.234132965s

wait4:   84.101255s
cpuacct: 84.104336222s

No entanto, para processos que demoram mais tempo, recebo um resultado diferente:

wait4:   155.309706s
cpuacct: 155.306291274s

wait4:   505.547594s
cpuacct: 505.526723631s

wait4:   897.180069s
cpuacct: 897.131232685s

Agora, o valor de cpuacct é um pouco menor, o que eu nunca esperaria que acontecesse. Alguém tem uma ideia de por que isso acontece?

Eu não me preocupo com a precisão de 0,1s, e nunca experimentei uma diferença maior. Posso estar confiante de que a diferença será sempre tão pequena? Ou existem cenários possíveis em que a diferença será maior?

A documentação cpuacct indica que o valor pode ser impreciso em 2 casos. No entanto, ambos os casos não se aplicam aqui, como estou em uma máquina de 64 bits, e posso esperar uma quantidade arbitrária de tempo após a conclusão do processo, a leitura de cpuacct.usage permanecerá constante (por isso acredito firmemente que não é um desatualizado) valor).

Configuração precisa:
Meu processo de partida é um processo Python. Eu uso subprocess.Popen() para gerar a tarefa e os.wait4() para obter o tempo. Para usar os cgroups, passo uma função para o parâmetro preexec_fn de Popen que adiciona o novo processo ao cgroup (portanto, isso é feito entre as chamadas de sistema fork e exec ). O processo iniciado é uma VM Java. Eu não acho que isso seja relevante, mas eu queria fornecer essa informação apenas no caso.

    
por Philipp Wendler 14.01.2013 / 13:23

0 respostas

Tags