CPU de monitoreo de rendimiento de Linux

CPU de monitoreo de rendimiento de Linux

1. Introducción a la CPU

El programador del kernel será responsable de programar dos tipos de recursos: subprocesos (únicos o múltiples) e interrupciones .
El planificador define diferentes prioridades para diferentes recursos.

Prioridad: Interrupciones (interrupción) > Procesos del kernel (sistema) (procesamiento del kernel/proceso del sistema) > Procesos de usuario (proceso de usuario)

**Interrupciones (interrupción)**: El dispositivo notifica al kernel que ha completado un proceso de procesamiento de datos. Por ejemplo, cuando un dispositivo de tarjeta de red entrega paquetes de red o una pieza de hardware proporciona una solicitud de E/S.

Procesos del kernel (sistema) : todos los procesos del kernel controlan la prioridad.

Procesos de usuario : todos los programas de software se ejecutan en el espacio del usuario. Este bloque tiene baja prioridad en el mecanismo de programación del kernel.

Nos centramos en las siguientes 3 partes de la CPU:

  • utilización
  • contexto (cambio de contexto)
  • ejecutar colas

2. Utilización de la CPU

La utilización de la CPU se define como un porcentaje del uso de la CPU y depende principalmente de qué recursos intentan acceder a la CPU. Una de las métricas más importantes para evaluar un sistema es observar la utilización de la CPU. Para lograr el mayor rendimiento o escalabilidad de una aplicación, esta debe aprovechar al máximo los ciclos de CPU que se le asignan sin desperdiciar ninguno.

Una aplicación que consume mucha CPU no significa que el rendimiento o la escalabilidad estén al máximo. Para saber cómo una aplicación utiliza los ciclos de la CPU, es necesario monitorear el uso de la CPU del sistema. Si una CPU se utiliza por completo, la proporción equilibrada entre las categorías de utilización debe ser:

  • 65 % - 70 % del tiempo de usuario
  • 30% - 35% Tiempo del sistema
  • 0% - 5% Tiempo inactivo

La utilización de la CPU se clasifica de la siguiente manera:

Tiempo de usuario (tiempo de proceso del usuario) : aproximadamente el porcentaje de tiempo de sobrecarga de CPU del proceso ejecutado en el espacio del usuario.

El uso de CPU en modo de usuario se refiere al porcentaje de tiempo dedicado a ejecutar el código de la aplicación como porcentaje del tiempo total de CPU.

Tiempo del sistema (subproceso del kernel y tiempo de interrupción): respecto al porcentaje de tiempo de sobrecarga de la CPU para subprocesos e interrupciones en el espacio del kernel.

El uso de la CPU del estado del sistema se refiere al porcentaje de tiempo que la aplicación ejecuta llamadas al sistema operativo respecto del tiempo total de la CPU.

El uso elevado de CPU en el estado del sistema significa que hay competencia por recursos compartidos o hay mucha interacción entre dispositivos de E/S.
Idealmente, cuando una aplicación alcanza el máximo rendimiento y escalabilidad, el uso de la CPU del sistema es del 0%. Por lo tanto, es necesario reducir el uso de la CPU del sistema tanto como sea posible.

Esperar IO (tiempo de espera de solicitud de IO): el porcentaje de tiempo de inactividad de la CPU en el que todos los subprocesos del proceso están bloqueados esperando para completar una solicitud de IO.

Inactivo: el porcentaje de tiempo que un proceso en estado completamente inactivo pasa en el procesador de la CPU.

3. Supervisar la CPU

3.1 Utilice la parte superior para monitorear el uso de la CPU

Insertar descripción de la imagen aquí

La mitad superior es la información estadística de todo el sistema y la mitad inferior es la información estadística de cada proceso. De forma predeterminada, está ordenada de mayor a menor según el uso de CPU.

3.2 Utilice vmstat para monitorear el uso de la CPU

Insertar descripción de la imagen aquí

contenido ilustrar
a nosotros Uso de CPU en modo usuario
y Estado del sistema (kernel e interrupción) Uso de CPU
identificación Tasa de inactividad o tasa de disponibilidad de CPU
de Porcentaje de todos los subprocesos ejecutables bloqueados en espera de solicitudes de IO

nosotros+sy+id=100

3.3 Utilice mpstat para monitorear el uso de la CPU

El kernel de Linux considera que un procesador de doble núcleo tiene 2 CPU, por lo que un procesador de doble núcleo con dos núcleos informará que hay 4 CPU disponibles.

El valor estadístico de la utilización de la CPU proporcionado por el comando mpstat es aproximadamente el mismo que el de vmstat, pero mpstat puede monitorear el uso de la CPU de cada procesador virtual , lo que ayuda a encontrar que algunos subprocesos en la aplicación consumen más ciclos de CPU que otros subprocesos. O todos los subprocesos de la aplicación básicamente comparten los ciclos de la CPU por igual. Si es lo último, significa que la escalabilidad de la aplicación es mejor.

Si no se especifica el intervalo de informes de mpstat, se genera la suma de todos los datos de mpstat desde la última vez que se inició el sistema.

Insertar descripción de la imagen aquí

contenido ilustrar
usr Porcentaje de tiempo de CPU dedicado a ejecutar código de usuario
sistema Porcentaje de tiempo de CPU dedicado a ejecutar código del kernel
yo espero Indica el tiempo de espera de IO
inactivo Representa el porcentaje de tiempo de inactividad de la CPU.

Utilice mpstat para monitorear el uso de CPU de cada procesador virtual:

Insertar descripción de la imagen aquí

-P 0 significa especificar ver el uso de la primera CPU (el subíndice comienza desde 0)

3.4 Utilice pidstat para monitorear el uso de CPU individual

Ejemplo: aumente el uso de la CPU ejecutando el script WhileTrue.py y vea el uso de la CPU del proceso. Comando: pidstat -u 1 -p 3336

Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

4. Razones de la inactividad de la CPU

  • La aplicación está bloqueada por la primitiva de sincronización y no puede continuar su ejecución hasta que se libere el bloqueo.
  • La aplicación está esperando algo, como una respuesta de una llamada a la base de datos.
  • La aplicación realmente no hace nada.

5. Ejecutar colas

Cada CPU mantiene una cola de ejecución de subprocesos. En teoría, el programador debería estar ejecutándose y ejecutando subprocesos constantemente. El subproceso del proceso está en estado de suspensión (bloqueado y esperando IO) o en estado ejecutable.

Si el subsistema de la CPU tiene una carga elevada, significa que el programador del kernel no podrá responder a las solicitudes del sistema de manera oportuna. Provoca que los procesos ejecutables se congestionen en la cola de ejecución. A medida que la cola de ejecución crece, los subprocesos del proceso tardarán más en ejecutarse.

Nota: Cada procesador no debe ejecutar más de 1 a 3 subprocesos en la cola. Por ejemplo, un procesador de doble núcleo no debe tener más de 6 subprocesos en la cola de ejecución.

La cola de ejecución contiene procesos livianos que están listos para ejecutarse y esperan la CPU disponible. Si la cantidad de procesos livianos listos para ejecutar excede el límite superior que el sistema puede manejar, la cola de ejecución será muy larga. La carga del sistema de nombres de tablas largas de la cola de ejecución puede estar saturada.

**Cuando la longitud de la cola de ejecución del sistema es igual a la cantidad de procesadores virtuales, los usuarios no notarán ninguna degradación del rendimiento. **La cantidad de procesadores virtuales aquí es la cantidad de subprocesos de hardware del sistema. Ese es el valor de retorno de Java API Runtime.availableProcessors(). Cuando la longitud de la cola de ejecución alcanza 4 veces o más que el procesamiento virtual, la respuesta del sistema es muy lenta.

El principio rector general es: si la longitud de la cola de ejecución ha sido más de 1 veces la cantidad de procesadores virtuales durante un largo período de tiempo, debe prestar atención. Si es de 3 a 4 veces, debe prestar atención. o tomar medidas inmediatamente.

5.1 Dos métodos para resolver la cola de larga duración

  • Aumentar la CPU para compartir la carga o reducir la cantidad de carga en el procesador reduce fundamentalmente la cantidad de subprocesos activos en cada procesador virtual, reduciendo así la cantidad de procesos livianos en la cola de ejecución.

  • Busque formas de reducir los ciclos de CPU necesarios para ejecutar su aplicación, como reducir la frecuencia de recolección de basura o usar algoritmos que realicen la misma tarea con menos instrucciones de CPU.

5.2 Utilice la parte superior para ver el estado detallado de la cola de ejecución

La carga se refiere a la combinación de cuántos subprocesos hay en la cola de la CPU y cuántos subprocesos de proceso se están ejecutando actualmente.
Carga = número de procesos livianos en ejecución + número de procesos livianos en la cola de ejecución.
Por ejemplo: si un sistema de doble núcleo ejecuta 2 subprocesos y hay 4 en la cola de ejecución, la carga debe ser 6.

Los promedios de carga que se muestran en la parte superior se refieren a la carga dentro de 1 minuto, 5 minutos y 15 minutos respectivamente. Si la CPU es de un solo núcleo, entonces el valor superior a 1 es carga alta. Si la CPU es de cuatro núcleos, entonces el valor A por encima de 4 indica carga alta.

Palabra de experiencia: si una CPU tiene un número total de núcleos = 8 núcleos y la carga promedio teórica llega a 16, aún puede durar mucho tiempo.

5.3 Utilice vmstat para comprobar la longitud de la cola de ejecución

La primera columna generada por vmstat es la longitud de la cola de ejecución y el valor es el número real de procesos ligeros en la cola de ejecución.

Insertar descripción de la imagen aquí

6. Cambios de contexto

Incluso una CPU de un solo núcleo puede admitir la ejecución de código de subprocesos múltiples. La CPU implementa este mecanismo asignando intervalos de tiempo de CPU a cada subproceso. El intervalo de tiempo es el tiempo asignado por la CPU a cada subproceso. Debido a que el intervalo de tiempo es muy corto, la CPU sigue cambiando de subproceso para su ejecución, lo que nos hace sentir que se están ejecutando varios subprocesos al mismo tiempo. El intervalo de tiempo es generalmente decenas de milisegundos.

La CPU ejecuta tareas cíclicamente a través del algoritmo de asignación de intervalos de tiempo. Después de que la tarea actual ejecuta un intervalo de tiempo, cambiará a la siguiente tarea. Sin embargo, el estado de la tarea anterior se guarda antes de cambiar para que la próxima vez que vuelva a esta tarea, puede cargarla nuevamente El estado de la tarea. Por lo tanto, el proceso de una tarea desde guardar hasta recargar es un cambio de contexto, y el cambio de contexto de subproceso generalmente consume cientos de ciclos de reloj .

Cómo reducir el cambio de contexto

  1. En la programación concurrente sin bloqueos, el cambio de contexto se producirá cuando varios subprocesos compitan por los bloqueos.
  2. Algoritmo CAS, porque no se requiere bloqueo.
  3. Utilice hilos mínimos.
  4. Corrutinas: implemente la programación de múltiples tareas en un solo subproceso y mantenga el cambio entre múltiples tareas en un solo subproceso.

La mayoría de los procesadores modernos son capaces de ejecutar un proceso (un solo subproceso) o subprocesos. Los procesadores multiproceso tienen la capacidad de ejecutar varios subprocesos. Sin embargo, el kernel de Linux todavía trata cada núcleo del procesador del chip de doble núcleo como un procesador separado. Por ejemplo, un sistema con un kernel de Linux en un procesador de doble núcleo informa como dos procesadores independientes.

Un kernel de Linux estándar puede ejecutar de 50 a 50.000 subprocesos de procesamiento . Con una sola CPU, el kernel programa y equilibra cada hilo de proceso. A cada hilo se le asigna una cuota de tiempo para pasar en el procesador. A un subproceso se le ha asignado una cuota de tiempo o se ha adelantado a algo con una prioridad más alta (como una interrupción de hardware), en la que el subproceso de mayor prioridad se reubicará desde la zona a la cola del procesador. Esta relación de conversión de hilos es el cambio de contexto que mencionamos.

Cada vez que cambia el contexto del kernel, se utilizan recursos para cerrar el hilo en el registro de la CPU y colocarlo en la cola. Cuantos más cambios de contexto haya en el sistema, más trabajo realizará el núcleo bajo la gestión de programación del procesador.

El número de cambios de contexto está directamente relacionado con el uso de la CPU. Si la utilización de la CPU se mantiene en un estado equilibrado (65% - 70% del tiempo de usuario, 30% - 35% del tiempo del sistema, 0% - 5% del tiempo de inactividad), un Gran número de cambios de contexto. El cambio es normal .

El cambio de contexto se divide en:

  • Cambio de contexto preventivo
  • Cambio de contexto concesivo

El cambio de contexto concesivo significa que el subproceso de ejecución libera activamente la CPU , mientras que el cambio de contexto preventivo significa que el subproceso se ve obligado a renunciar a la CPU o es reemplazado por otros subprocesos de mayor prioridad porque el intervalo de tiempo asignado está agotado .

Una alta tasa de cambio de contexto preventivo indica que hay más subprocesos listos para ejecutar que procesadores virtuales disponibles. En este momento, generalmente puede ver una cola de ejecución larga, un alto uso de CPU, una gran cantidad de migraciones y una gran cantidad de conexiones con vmstat.cambios de contexto preventivos relacionados.

7. Supervisar los cambios de contexto

Monitoreo de vmstat:

Insertar descripción de la imagen aquí

pidstat -w monitoreo:

Insertar descripción de la imagen aquí

wt Ver cambio de contexto a nivel de subproceso:

Insertar descripción de la imagen aquí

pidstat -w informa que produce cambios de contexto por segundo en lugar de por intervalo de medición.
pidstat -w es un cambio de contexto para todos los procesadores.

cswch/s es un cambio de contexto concesional
nvcswch/s es un cambio de contexto preventivo

Pauta general: si los cambios de contexto de rendimiento ocupan el 5 % o más de sus ciclos de reloj, la aplicación Java está experimentando contención de bloqueo. Incluso entre el 3 % y el 5 % merece una investigación más profunda.

En versiones anteriores a Java 5, HotSpotVM delegaba casi toda la lógica de bloqueo a las primitivas de bloqueo del sistema operativo, lo que permitía a las herramientas del sistema operativo monitorear el estado del sistema, el uso de la CPU y smtx (número de giros en el mutex Spin on Mutex). La contención de bloqueos en aplicaciones Java se puede monitorear fácilmente.

En Java5, HotSpotVM implementa muchas lógicas de optimización de bloqueo, métodos de sincronización Java y bloques de sincronización en forma de código de usuario. Por lo tanto, el método anterior de usar mpstat para verificar el uso de la CPU de los estados del sistema smtx y sys no se puede usar y es necesario encontrar nuevas alternativas.

En Java 5 y superiores, si el bloqueo no se adquiere después de varios giros de bucle ocupado, el subproceso se suspende y espera a que se despierte antes de intentar adquirir el bloqueo nuevamente. Suspender y reactivar el subproceso provocará un cambio de contexto concesional por parte del operador. sistema, por lo que bloquea la competencia. Las aplicaciones severas exhibirán una gran cantidad de cambios de contexto de toma y daca.

El costo del ciclo de reloj de un cambio de contexto productivo es muy alto, generalmente hasta 80.000 ciclos de reloj (estos ciclos de reloj podrían haberse utilizado para ejecutar instrucciones del programa).

El número de ciclos de reloj desperdiciados al generar cambios de contexto se puede calcular dividiendo el número de cambios de contexto en pidstat -w por el número de procesadores virtuales. Nota: pidstat -w es un cambio de contexto de rendimiento para todos los procesadores virtuales. Multiplique el número de cambios de contexto concesionales por 80 000 y divídalo por los ciclos de reloj de la CPU por segundo para obtener el porcentaje de ciclos de reloj de la CPU consumidos por el cambio de contexto concesional.

Ciclos de reloj estimados gastados por un cambio de contexto productivo:

Por ejemplo: el número de cambios de contexto concesionales es 8000/s, 8000*80000 (coste del ciclo de reloj del cambio de contexto general) = 640 000 000 ciclos de reloj, un procesador de 3,0 GHz puede ejecutar 3000 000 000 (3 mil millones) de ciclos de reloj por segundo ciclos, por lo que 640 000 000/3 000 000 000 = 21,33% de los ciclos de reloj disponibles. Significa que la aplicación Java se enfrenta a una competencia de bloqueo, que puede deberse a que varios subprocesos acceden al mismo método sincronizado o bloque sincronizado, o puede deberse a que el código está protegido por una estructura de bloqueo de Java como java.util.concurrent. .cerraduras.Bloquear.

Por ejemplo: cswch/s=3500, hay 2 procesadores, entonces el cambio de contexto de cada procesador es 3500/2=1750 y los ciclos de reloj consumidos son 1750*80000=140 000 000. El número de ciclos de reloj por segundo para La CPU de 3 GHz es 3 000 000 000, por lo que los ciclos de reloj desperdiciados por el cambio de contexto son 140 000 000/3 000 000 000 = 4,7%, lo que indica que la aplicación Java se enfrenta a una competencia de bloqueo.

8. Cómo comprobar qué CPU está ocupada por un proceso

while :; do  ps -eo pid,ni,pri,pcpu,psr,comm | grep 'python'; sleep 1;done

(La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (img-eXe2rYzA-1657590066014) (/Users/zy/Desktop/Notes/Performance Test/ imagen-20220712092414388.png)]
Insertar descripción de la imagen aquí

Como se muestra en la figura, la columna psr indica qué CPU ocupa el proceso. Como se muestra en la figura, parte del proceso python3 ocupa la primera CPU y parte ocupa la segunda CPU.

9. Ver información de la CPU

[root@iZbp1aqn43v9f9y956pim1Z huyan]# cat /proc/cpuinfo 
processor       : 0 //逻辑核数量
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8269CY CPU @ 2.50GHz //cpu的名称型号和主频
stepping        : 7
microcode       : 0x1
cpu MHz         : 2500.000 //实际主频
cache size      : 36608 KB
physical id     : 0 //单个cpu的标号
siblings        : 2 //单个cpu的逻辑核数
core id         : 0
cpu cores       : 1 //逻辑核所处cpu的物理核
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 22
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 arat avx512_vnni
bogomips        : 5000.00
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8269CY CPU @ 2.50GHz
stepping        : 7
microcode       : 0x1
cpu MHz         : 2500.000
cache size      : 36608 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 1
apicid          : 1
initial apicid  : 1
fpu             : yes
fpu_exception   : yes
cpuid level     : 22
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 arat avx512_vnni
bogomips        : 5000.00
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

Verifique el número total de CPU en la máquina:

[root@iZbp1aqn43v9f9y956pim1Z huyan]# cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
1

Verifique la cantidad de núcleos físicos de una sola CPU:

[root@iZbp1aqn43v9f9y956pim1Z huyan]# cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores       : 1

Verifique el número total de núcleos lógicos:

[root@iZbp1aqn43v9f9y956pim1Z huyan]# cat /proc/cpuinfo| grep "processor"| wc -l
2

Supongo que te gusta

Origin blog.csdn.net/u011090984/article/details/125736619
Recomendado
Clasificación