Solución 1:
No seguro, pero sobre todo en 1.00*n_cpu
.
La carga significa lo siguiente:si hay varios procesos en un sistema de una sola CPU, aparentemente se ejecutan en paralelo. Pero no es cierto. Lo que sucede en la práctica:el kernel le da 1/100 de segundo a un proceso y luego interrumpe su ejecución con una interrupción. Y da el siguiente 1/100 de segundo a otro proceso.
Prácticamente la pregunta, "¿qué proceso debería obtener nuestro siguiente intervalo de 1/100 de segundo?", se decidirá mediante una heurística compleja. Se nombra como tarea programación .
Por supuesto, los procesos que están bloqueados, por ejemplo, están esperando sus datos para leer del disco, están exentos de esta programación de tareas.
Lo que dice la carga:cuántos procesos están esperando actualmente su próximo marco de tiempo de 1/100 de segundo. Por supuesto, es un valor medio. Esto se debe a que puede ver varios números en un cat /proc/loadavg
.
La situación en un sistema multi-cpu es un poco más compleja. Hay múltiples cpus, cuyos marcos de tiempo se pueden dar a múltiples procesos. Eso hace que la programación de tareas sea un poco, pero no demasiado, más compleja. Pero la situación es la misma.
El kernel es inteligente, trata de compartir los recursos del sistema para una eficiencia óptima, y está cerca de eso (hay cosas menores de optimización, por ejemplo, es mejor si un proceso se ejecutará el mayor tiempo posible en el mismo cpu debido a consideraciones de almacenamiento en caché, pero no importa allí). Esto se debe a que si tenemos la carga 8, eso significa que en realidad hay 8 procesos esperando su próxima porción de tiempo. Si tenemos 8 CPU, podemos asignar estos intervalos de tiempo a la CPU uno a uno y, por lo tanto, nuestro sistema se utilizará de manera óptima.
Si ves un top
, puede ver que el número de procesos reales en ejecución es sorprendentemente bajo:son los procesos marcados con R
allá. Incluso en un sistema que no es realmente extremo, a menudo está por debajo de 5. Esto se debe en parte a que los procesos que esperan sus datos de los discos o de la red también están suspendidos (marcados con S
en la parte superior). La carga muestra solo el uso de la CPU.
También hay herramientas para medir la carga del disco, en mi humilde opinión, deberían ser al menos importantes como el monitoreo del uso de la CPU, pero de alguna manera no es tan conocido aquí en nuestro mundo profesional de administradores de sistemas.
Las herramientas de Windows a menudo dividen la carga con el número real de CPU. Esto hace que algunos administradores profesionales de sistemas de Windows usen la carga del sistema en este sentido de división por CPU. No tienen razón y probablemente estarán más felices después de que les expliques esto.
Las CPU multinúcleo son prácticamente varias CPU en el mismo chip de silicio. No hay diferencia.
En el caso de las CPU con hiperprocesamiento, existe un efecto secundario interesante:cargar una CPU hace que sus pares con hiperprocesamiento sean más lentos. Pero esto sucede en una capa más profunda de lo que maneja la programación normal de tareas, aunque puede (y debe) influir en las decisiones de movimiento del proceso del programador.
Pero desde nuestro punto de vista actual, lo que determina la carga del sistema, tampoco importa.
Solución 2:
El promedio de carga no significa lo que crees que significa. No se trata del uso instantáneo de la CPU, sino de cuántos procesos están esperando para ejecutarse. Por lo general eso se debe a que muchas cosas necesitan CPU, pero no siempre. Un culpable común es un proceso que espera E/S:disco o red.
Intenta ejecutar ps -e v
y buscando banderas de estado de proceso.
state The state is given by a sequence of characters, for example, "RWNA". The first character indicates the run state of the process:
D Marks a process in disk (or other short term, uninterruptible) wait.
I Marks a process that is idle (sleeping for longer than about 20 seconds).
L Marks a process that is waiting to acquire a lock.
R Marks a runnable process.
S Marks a process that is sleeping for less than about 20 seconds.
T Marks a stopped process.
W Marks an idle interrupt thread.
Z Marks a dead process (a "zombie").
Esto es del ps
página de manual, para que pueda encontrar más detalles allí - R
y D
Los procesos son probablemente de particular interés.
Puede terminar con 'picos' promedio de carga por todo tipo de razones, por lo que no son realmente una buena medida de otra cosa que no sea 'este sistema está ocupado'. Atascarse en el mapeo del promedio de carga a los núcleos de la CPU no le servirá de nada.
Solución 3:
Como hyperthreading no es en realidad un segundo núcleo, nunca llevará un núcleo al 200 %, pero lo llevará más allá del 100 % para ciertas cargas de trabajo.
Por lo tanto, su carga máxima se desconoce entre aproximadamente 4 y 6
(por supuesto, esto puede aumentar más cuando está sobrecargado porque en realidad cuenta los procesos ejecutables, particularmente cuando están esperando IO)
Solución 4:
En un sistema Linux, no solo se cuentan los procesos en la cola ejecutable para calcular la carga, sino también aquellos en estado de suspensión ininterrumpida, wikipedia, lo que hace que la carga aumente cuando hay muchos procesos esperando por el disco.
Solución 5:
Hice algunos experimentos en nuestro sistema Xeon de 24 núcleos (2 sockets x 12 núcleos). La carga máxima es 48,0 en este caso debido a la forma en que Linux configura el hiperprocesamiento.
Sin embargo, no obtiene el equivalente a 48 núcleos de rendimiento. Lo que he observado es que se obtiene aproximadamente el 90 % del rendimiento en los primeros 24 procesadores lógicos, es decir, si la carga llega a 24.0. Luego obtiene un rendimiento adicional de alrededor del 10 % para los 24 procesadores lógicos restantes (la carga llega a 48,0). Otra forma de pensarlo es que si ejecuta 48 subprocesos en los 24 núcleos, obtendrá un aumento de alrededor del 10-20% si habilita Hyperthreading versus no. No es un impulso del 100 % como implicarían los chicos de marketing.
Por ejemplo, una forma de probar esta observación es tener un proceso que ejecute 48 subprocesos (por ejemplo, usando TBB o un modelo de subprocesos manual), luego ejecute
time numactl --physcpubind=0-23 ./myprocess
y luego ejecutar
time numactl --physcpubind=0-47 ./myprocess
Este último debería ejecutarse en aproximadamente un 10-20% menos de tiempo. Si su proceso está altamente bloqueado por E/S, entonces el resultado podría ser diferente.
El primero deshabilitará el hyperthreading al permitir que los subprocesos se ejecuten en un solo procesador lógico (de cada núcleo), mientras que el segundo habilitará el hyperthreading al permitir que los subprocesos se ejecuten en 2 procesadores lógicos (de cada núcleo).
La carga en ambos casos debe informarse como 48,0... lo que, como puede ver, es muy engañoso.