Top e ps não mostrando o mesmo resultado de cpu

48

Isso está vinculado a esta pergunta.

Quando executo top , obtenho o seguinte resultado:

pid3038estáusando18%decpu,noentanto,quandoexecutando

o resultado é de 5,5%. E este número não parece estar mudando com o tempo (ou seja, ao executar o mesmo comando um pouco mais tarde) ...

O comando ps está calculando a média do uso da cpu?

    
por Theodor 15.12.2012 / 12:33

2 respostas

78

man ps em NOTES seção.

   CPU usage is currently expressed as the percentage of time spent running
   during the entire lifetime of a process.  This is not ideal, and it does not
   conform to the standards that ps otherwise conforms to.  CPU usage is
   unlikely to add up to exactly 100%.

E, suponha que você saiba, mas você também pode fazer:

top -p <PID>

Editar : quanto ao seu comentário sobre outra resposta;

"Hmm yeah i Wonder how to get that (the instant CPU percentage) from ps"

Resposta curta: você não pode.

Por que isso acontece?

É como pedir a alguém para calcular a velocidade de um carro a partir de uma foto.

Embora top seja uma ferramenta de monitoramento, ps é uma ferramenta de instantâneo. Pense nisso assim: A qualquer momento, um processo usa a CPU ou não. Assim, você tem 0% ou 100% de carga naquele exato momento.

Dando: Se ps devesse dar uso instantâneo da CPU , seria 0% ou 100%.

Por outro lado,

top mantém os números de pesquisa e calcula a carga ao longo do tempo.

ps poderia ter dado uso atual - mas isso exigiria que ele lesse dados várias vezes e dormisse entre cada leitura. Isso não acontece.

Cálculo para ps% cpu

ps calcula o uso da CPU da seguinte maneira:

uptime  = total time system has been running.
ps_time = process start time measured in seconds from boot.
pu_time = total time process has been using the CPU.

;; Seconds process has been running:
seconds   = uptime - ps_time
;; Usage:
cpu_usage = pu_time * 1000 / seconds

print: cpu_usage / 10 "." cpu_usage % 10


Example: uptime = 344,545 ps_time = 322,462 pu_time = 3,383 seconds = 344,545 - 322,462 = 22,083 cpu_usage = 3,383 * 1,000 / 22,083 = 153 print: 153 / 10 "." 153 % 10 => 15.3

Assim, o número impresso é: tempo que o processo tem usado a CPU durante sua vida útil. Como no exemplo acima. Isso ocorreu em 15,3% de sua vida útil. Em 84,7% das vezes, ele não estava incomodando a CPU.

Recuperação de dados

ps , bem como top , usa dados de arquivos armazenados em /proc/ - ou o processo de pseudo-sistema de arquivos de informação .

Você tem alguns arquivos na raiz de /proc/ que possuem várias informações sobre o estado geral do sistema. Além disso, cada processo tem sua própria subpasta /proc/<PID>/ , onde os dados específicos do processo são armazenados. Por exemplo, o processo da sua pergunta tinha uma pasta em /proc/3038/ .

Quando ps calcula o uso da CPU, ele usa dois arquivos:

/proc/uptime      The uptime of the system (seconds), and the amount of time spent in idle process (seconds).
/proc/[PID]/stat  Status information about the process.
  • A partir de uptime , ele usa o primeiro valor ( tempo de atividade ).
  • De [PID]/stat , usa o seguinte:
 #  Name      Description
14  utime     CPU time spent in user code, measured in jiffies
15  stime     CPU time spent in kernel code, measured in jiffies
16  cutime    CPU time spent in user code, including time from children
17  cstime    CPU time spent in kernel code, including time from children 
22  starttime Time when the process started, measured in jiffies

Um jiffie é o tick do relógio. Então, além disso, ele usa vários métodos, por exemplo, sysconf(_SC_CLK_TCK) , para obter o Hertz do sistema (número de tiques por segundo) - em última análise, usando 100 como um retorno após esgotar outras opções.

Portanto, se utime for 1234 e Hertz for 100, então:

seconds = utime / Hertz = 1234 / 100 = 12.34

O cálculo real é feito por:

total_time = utime + stime

IF include_dead_children
    total_time = total_time + cutime + cstime
ENDIF

seconds = uptime - starttime / Hertz

pcpu = (total_time * 1000 / Hertz) / seconds

print: "%CPU" pcpu / 10 "." pcpu % 10

Exemplo (Saída de um script Bash personalizado):

$ ./psw2 30894
System information
           uptime : 353,512 seconds
             idle : 0
Process information
              PID : 30894
         filename : plugin-containe
            utime : 421,951 jiffies 4,219 seconds
            stime : 63,334 jiffies 633 seconds
           cutime : 0 jiffies 0 seconds
           cstime : 1 jiffies 0 seconds
        starttime : 32,246,240 jiffies 322,462 seconds

Process run time  : 31,050
Process CPU time  : 485,286 jiffies 4,852 seconds
CPU usage since birth: 15.6%

Calculando carregamento "atual" com ps

Este é um esforço (bit?) obscuro, mas está bem. Vamos ter uma chance.

Pode-se usar tempos fornecidos por ps e calcular o uso da CPU a partir disso. Ao pensar sobre isso, pode ser bastante útil, com algumas limitações.

Isso pode ser útil para calcular o uso da CPU durante um período mais longo. Ou seja Digamos que você queira monitorar a carga média da CPU de plugin-container no Firefox enquanto faz alguma tarefa relacionada ao Firefox.

Usando a saída de:

$ ps -p -o cputime, etimes

CODE    HEADER   DESCRIPTION
cputime TIME     cumulative CPU time, "[DD-]hh:mm:ss" format.  (alias time).
etime   ELAPSED  elapsed time since the process was started, [DD-]hh:]mm:ss.
etimes  ELAPSED  elapsed time since the process was started, in seconds.

Eu uso etime sobre etimes nesta amostra, em cálculos, apenas para ficar um pouco mais claro. Também adiciono% cpu para "diversão". Em um script básico, obviamente, seria usado etimes - ou melhor leitura de /proc/<PID>/ etc.

Start:
$ ps -p 30894 -o %cpu,cputime,etime,etimes
%CPU     TIME     ELAPSED ELAPSED
 5.9 00:13:55    03:53:56   14036

End:
%CPU     TIME     ELAPSED ELAPSED
 6.2 00:14:45    03:56:07   14167

Calculate times:
            13 * 60 + 55 =    835   (cputime this far)
3 * 3,600 + 53 * 60 + 56 = 14,036   (time running this far)

            14 * 60 + 45 =    885   (cputime at end)
3 * 3,600 + 56 * 60 +  7 = 14,167   (time running at end)

Calculate percent load:
((885 - 835) / (14,167 - 14,036)) * 100 = 38

O processo estava usando a CPU 38% do tempo durante esse período.

Veja o código

Se você quer saber como ps faz isso, e sabe um pouco C, fazer (parece que você executa o Gnome Debain deriavnt) - boa atitude no código em relação a comentários, etc:

apt-get source procps
cd procps*/ps
vim HACKING
    
por 15.12.2012 / 13:02
3
man top

%CPU  --  CPU usage
The  task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.  In a true SMP environment, if 'Irix
mode' is Off, top will operate in 'Solaris mode' where a task's cpu usage will be divided by the total number of CPUs.  You toggle  'Irix/Solaris'  modes
with the 'I' interactive command.


man ps 
%cpu       %CPU    cpu utilization of the process in "##.#" format. Currently, it is the CPU time used divided by the time the process has been running                       (cputime/realtime ratio), expressed as a percentage. It will not add up to 100% unless you are lucky. (alias pcpu).
    
por 15.12.2012 / 13:16

Tags