top - ¿Cálculo exacto del uso de CPU dado en porcentaje en Linux?
ver procesos que consumen mas memoria linux (3)
Es una pregunta que se ha hecho muchas veces, sin embargo, no hay una respuesta bien respaldada que pueda encontrar.
Muchas personas sugieren el uso del comando superior, pero si ejecutas una vez la parte superior (porque tienes un script, por ejemplo, recolectando el uso de la CPU cada 1 segundo), siempre dará el mismo resultado de uso de la CPU ( ejemplo 1 , ejemplo 2 ).
Una forma más precisa de calcular el uso de la CPU es leyendo los valores de /proc/stat
, pero la mayoría de las respuestas solo usan los primeros 4 campos de /proc/stat
para calcularlo (un ejemplo aquí ).
/proc/stat/
tiene 10 campos por núcleo de CPU a partir del núcleo de Linux 2.6.33!
También encontré esta Utilización precisa de la CPU en Linux utilizando la pregunta / proc / stat que señala el mismo problema, -que la mayoría de las otras preguntas solo toman en consideración 4 de los muchos campos- pero la respuesta aquí comienza con "I pensar "(no es seguro), y excepto eso, solo le preocupan los primeros 7 campos (de 10 en /proc/stat/
)
Esta secuencia de comandos perl usa todos los campos para calcular el uso de la CPU, lo cual, una vez más, no creo que sea correcto después de una investigación adicional.
Después de echar un vistazo rápido al código del núcleo aquí , parece que, por ejemplo, guest_nice
y guest fields
siempre están aumentando junto con nice
y user
(por lo que no deberían incluirse en el cálculo de uso de la CPU, ya que están incluidos en nice
y campos de user
ya)
/*
* Account guest cpu time to a process.
* @p: the process that the cpu time gets accounted to
* @cputime: the cpu time spent in virtual machine since the last update
* @cputime_scaled: cputime scaled by cpu frequency
*/
static void account_guest_time(struct task_struct *p, cputime_t cputime,
cputime_t cputime_scaled)
{
u64 *cpustat = kcpustat_this_cpu->cpustat;
/* Add guest time to process. */
p->utime += cputime;
p->utimescaled += cputime_scaled;
account_group_user_time(p, cputime);
p->gtime += cputime;
/* Add guest time to cpustat. */
if (task_nice(p) > 0) {
cpustat[CPUTIME_NICE] += (__force u64) cputime;
cpustat[CPUTIME_GUEST_NICE] += (__force u64) cputime;
} else {
cpustat[CPUTIME_USER] += (__force u64) cputime;
cpustat[CPUTIME_GUEST] += (__force u64) cputime;
}
}
Entonces, para resumir, ¿cuál es una forma precisa de calcular el uso de la CPU en Linux y qué campos se deben considerar en los cálculos y cómo (qué campos se atribuyen al tiempo de inactividad y qué campos de tiempo no inactivo)?
Hola, también estaba investigando sobre el tema y encontré este hilo realmente útil. Usé la fórmula de Vangelis Tasoulas para escribir un pequeño script de python para esto. Adjunto está mi código Python para el problema. Carga el uso de la CPU por cpu_id cada segundo. Quizás también ayuda a otros. También los comentarios / sugerencias son bienvenidos :-)
#!/usr/bin/python
# -*- coding: utf-8 -*-
''''''
Created on 04.12.2014
@author: plagtag
''''''
from time import sleep
import sys
class GetCpuLoad(object):
''''''
classdocs
''''''
def __init__(self, percentage=True, sleeptime = 1):
''''''
@parent class: GetCpuLoad
@date: 04.12.2014
@author: plagtag
@info:
@param:
@return: CPU load in percentage
''''''
self.percentage = percentage
self.cpustat = ''/proc/stat''
self.sep = '' ''
self.sleeptime = sleeptime
def getcputime(self):
''''''
http://.com/questions/23367857/accurate-calculation-of-cpu-usage-given-in-percentage-in-linux
read in cpu information from file
The meanings of the columns are as follows, from left to right:
0cpuid: number of cpu
1user: normal processes executing in user mode
2nice: niced processes executing in user mode
3system: processes executing in kernel mode
4idle: twiddling thumbs
5iowait: waiting for I/O to complete
6irq: servicing interrupts
7softirq: servicing softirqs
#the formulas from htop
user nice system idle iowait irq softirq steal guest guest_nice
cpu 74608 2520 24433 1117073 6176 4054 0 0 0 0
Idle=idle+iowait
NonIdle=user+nice+system+irq+softirq+steal
Total=Idle+NonIdle # first line of file for all cpus
CPU_Percentage=((Total-PrevTotal)-(Idle-PrevIdle))/(Total-PrevTotal)
''''''
cpu_infos = {} #collect here the information
with open(self.cpustat,''r'') as f_stat:
lines = [line.split(self.sep) for content in f_stat.readlines() for line in content.split(''/n'') if line.startswith(''cpu'')]
#compute for every cpu
for cpu_line in lines:
if '''' in cpu_line: cpu_line.remove('''')#remove empty elements
cpu_line = [cpu_line[0]]+[float(i) for i in cpu_line[1:]]#type casting
cpu_id,user,nice,system,idle,iowait,irq,softrig,steal,guest,guest_nice = cpu_line
Idle=idle+iowait
NonIdle=user+nice+system+irq+softrig+steal
Total=Idle+NonIdle
#update dictionionary
cpu_infos.update({cpu_id:{''total'':Total,''idle'':Idle}})
return cpu_infos
def getcpuload(self):
''''''
CPU_Percentage=((Total-PrevTotal)-(Idle-PrevIdle))/(Total-PrevTotal)
''''''
start = self.getcputime()
#wait a second
sleep(self.sleeptime)
stop = self.getcputime()
cpu_load = {}
for cpu in start:
Total = stop[cpu][''total'']
PrevTotal = start[cpu][''total'']
Idle = stop[cpu][''idle'']
PrevIdle = start[cpu][''idle'']
CPU_Percentage=((Total-PrevTotal)-(Idle-PrevIdle))/(Total-PrevTotal)*100
cpu_load.update({cpu: CPU_Percentage})
return cpu_load
if __name__==''__main__'':
x = GetCpuLoad()
while True:
try:
data = x.getcpuload()
print data
except KeyboardInterrupt:
sys.exit("Finished")
De acuerdo con el código fuente htop en el momento de la escritura, mis suposiciones parecen ser válidas:
(vea la función void ProcessList_scan(ProcessList* this)
en ProcessList.c )
// Guest time is already accounted in usertime
usertime = usertime - guest; # As you see here, it subtracts guest from user time
nicetime = nicetime - guestnice; # and guest_nice from nice time
// Fields existing on kernels >= 2.6
// (and RHEL''s patched kernel 2.4...)
idlealltime = idletime + ioWait; # ioWait is added in the idleTime
systemalltime = systemtime + irq + softIrq;
virtalltime = guest + guestnice;
totaltime = usertime + nicetime + systemalltime + idlealltime + steal + virtalltime;
Y así, de los campos enumerados en la primera línea de /proc/stat
: (ver sección 1.8 en la documentación )
user nice system idle iowait irq softirq steal guest guest_nice
cpu 74608 2520 24433 1117073 6176 4054 0 0 0 0
Algorítmicamente, podemos calcular el porcentaje de uso de CPU como:
PrevIdle = previdle + previowait
Idle = idle + iowait
PrevNonIdle = prevuser + prevnice + prevsystem + previrq + prevsoftirq + prevsteal
NonIdle = user + nice + system + irq + softirq + steal
PrevTotal = PrevIdle + PrevNonIdle
Total = Idle + NonIdle
# differentiate: actual value minus the previous one
totald = Total - PrevTotal
idled = Idle - PrevIdle
CPU_Percentage = (totald - idled)/totald
El siguiente es un script bash que se basa en la respuesta de Vangelis. Produce resultados como este:
total 49.1803
cpu0 14.2857
cpu1 100
cpu2 28.5714
cpu3 100
cpu4 30
cpu5 25
Crea un archivo llamado get_cpu_usage.sh
Ejecútelo usando el siguiente comando: bash get_cpu_usage.sh 0.2
El argumento es la cantidad de segundos para medir. En este caso, son 200 milisegundos.
Los contenidos son:
#!/bin/sh
sleepDurationSeconds=$1
previousDate=$(date +%s%N | cut -b1-13)
previousStats=$(cat /proc/stat)
sleep $sleepDurationSeconds
currentDate=$(date +%s%N | cut -b1-13)
currentStats=$(cat /proc/stat)
cpus=$(echo "$currentStats" | grep -P ''cpu'' | awk -F " " ''{print $1}'')
for cpu in $cpus
do
currentLine=$(echo "$currentStats" | grep "$cpu ")
user=$(echo "$currentLine" | awk -F " " ''{print $2}'')
nice=$(echo "$currentLine" | awk -F " " ''{print $3}'')
system=$(echo "$currentLine" | awk -F " " ''{print $4}'')
idle=$(echo "$currentLine" | awk -F " " ''{print $5}'')
iowait=$(echo "$currentLine" | awk -F " " ''{print $6}'')
irq=$(echo "$currentLine" | awk -F " " ''{print $7}'')
softirq=$(echo "$currentLine" | awk -F " " ''{print $8}'')
steal=$(echo "$currentLine" | awk -F " " ''{print $9}'')
guest=$(echo "$currentLine" | awk -F " " ''{print $10}'')
guest_nice=$(echo "$currentLine" | awk -F " " ''{print $11}'')
previousLine=$(echo "$previousStats" | grep "$cpu ")
prevuser=$(echo "$previousLine" | awk -F " " ''{print $2}'')
prevnice=$(echo "$previousLine" | awk -F " " ''{print $3}'')
prevsystem=$(echo "$previousLine" | awk -F " " ''{print $4}'')
previdle=$(echo "$previousLine" | awk -F " " ''{print $5}'')
previowait=$(echo "$previousLine" | awk -F " " ''{print $6}'')
previrq=$(echo "$previousLine" | awk -F " " ''{print $7}'')
prevsoftirq=$(echo "$previousLine" | awk -F " " ''{print $8}'')
prevsteal=$(echo "$previousLine" | awk -F " " ''{print $9}'')
prevguest=$(echo "$previousLine" | awk -F " " ''{print $10}'')
prevguest_nice=$(echo "$previousLine" | awk -F " " ''{print $11}'')
PrevIdle=$((previdle + previowait))
Idle=$((idle + iowait))
PrevNonIdle=$((prevuser + prevnice + prevsystem + previrq + prevsoftirq + prevsteal))
NonIdle=$((user + nice + system + irq + softirq + steal))
PrevTotal=$((PrevIdle + PrevNonIdle))
Total=$((Idle + NonIdle))
totald=$((Total - PrevTotal))
idled=$((Idle - PrevIdle))
CPU_Percentage=$(awk "BEGIN {print ($totald - $idled)/$totald*100}")
if [[ "$cpu" == "cpu" ]]; then
echo "total "$CPU_Percentage
else
echo $cpu" "$CPU_Percentage
fi
done