Tengo una máquina virtual Ubuntu, que se ejecuta dentro de Xen XCP basado en Ubuntu. Aloja un servicio HTTP personalizado basado en FCGI, detrás nginx
.
Bajo carga desde ab
el primer núcleo de la CPU está saturado, y el resto está subcargado.
En /proc/interrupts
veo que CPU0 sirve un orden de magnitud más interrupciones que cualquier otro núcleo. La mayoría de ellos provienen de eth1
.
¿Hay algo que pueda hacer para mejorar el rendimiento de esta VM? ¿Hay alguna forma de equilibrar las interrupciones de manera más uniforme?
Detalles sangrientos:
$ uname -a Linux MYHOST 2.6.38-15-virtual # 59-Ubuntu SMP viernes 27 de abril 16:40:18 UTC 2012 i686 i686 i386 GNU / Linux $ lsb_release -a No hay módulos LSB disponibles. ID de distribuidor: Ubuntu Descripción: Ubuntu 11.04 Lanzamiento: 11.04 Nombre en clave: natty $ cat / proc / interrupciones CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 283: 113720624 0 0 0 0 0 0 0 xen-dyn-event eth1 284: 1 0 0 0 0 0 0 0 xen-dyn-event eth0 285: 2254 0 0 3873799 0 0 0 0 xen-dyn-event blkif 286: 23 0 0 0 0 0 0 0 xen-dyn-event hvc_console 287: 492 42 0 0 0 0 0 295324 xen-dyn-event xenbus 288: 0 0 0 0 0 0 0 222294 xen-percpu-ipi callfuncsingle7 289: 0 0 0 0 0 0 0 0 xen-percpu-virq debug7 290: 0 0 0 0 0 0 0 151302 xen-percpu-ipi callfunc7 291: 0 0 0 0 0 0 0 3236015 xen-percpu-ipi resched7 292: 0 0 0 0 0 0 0 60064 xen-percpu-ipi spinlock7 293: 0 0 0 0 0 0 0 12355510 temporizador xen-percpu-virq7 294: 0 0 0 0 0 0 803174 0 xen-percpu-ipi callfuncsingle6 295: 0 0 0 0 0 0 0 0 xen-percpu-virq debug6 296: 0 0 0 0 0 0 60027 0 xen-percpu-ipi callfunc6 297: 0 0 0 0 0 0 5374762 0 xen-percpu-ipi resched6 298: 0 0 0 0 0 0 64976 0 xen-percpu-ipi spinlock6 299: 0 0 0 0 0 0 15294870 0 temporizador xen-percpu-virq6 300: 0 0 0 0 0 264441 0 0 xen-percpu-ipi callfuncsingle5 301: 0 0 0 0 0 0 0 0 xen-percpu-virq debug5 302: 0 0 0 0 0 79324 0 0 xen-percpu-ipi callfunc5 303: 0 0 0 0 0 3468144 0 0 xen-percpu-ipi resched5 304: 0 0 0 0 0 66269 0 0 xen-percpu-ipi spinlock5 305: 0 0 0 0 0 12778464 0 0 temporizador xen-percpu-virq5 306: 0 0 0 0 844591 0 0 0 xen-percpu-ipi callfuncsingle4 307: 0 0 0 0 0 0 0 0 xen-percpu-virq debug4 308: 0 0 0 0 75293 0 0 0 xen-percpu-ipi callfunc4 309: 0 0 0 0 3482146 0 0 0 xen-percpu-ipi resched4 310: 0 0 0 0 79312 0 0 0 xen-percpu-ipi spinlock4 311: 0 0 0 0 21642424 0 0 0 xen-percpu-virq timer4 312: 0 0 0 449141 0 0 0 0 xen-percpu-ipi callfuncsingle3 313: 0 0 0 0 0 0 0 0 xen-percpu-virq debug3 314: 0 0 0 95405 0 0 0 0 xen-percpu-ipi callfunc3 315: 0 0 0 3802992 0 0 0 0 xen-percpu-ipi resched3 316: 0 0 0 76607 0 0 0 0 xen-percpu-ipi spinlock3 317: 0 0 0 16439729 0 0 0 0 xen-percpu-virq timer3 318: 0 0 876383 0 0 0 0 0 xen-percpu-ipi callfuncsingle2 319: 0 0 0 0 0 0 0 0 xen-percpu-virq debug2 320: 0 0 76416 0 0 0 0 0 xen-percpu-ipi callfunc2 321: 0 0 3422476 0 0 0 0 0 xen-percpu-ipi resched2 322: 0 0 69217 0 0 0 0 0 xen-percpu-ipi spinlock2 323: 0 0 10247182 0 0 0 0 0 xen-percpu-virq timer2 324: 0 393514 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle1 325: 0 0 0 0 0 0 0 0 xen-percpu-virq debug1 326: 0 95773 0 0 0 0 0 0 xen-percpu-ipi callfunc1 327: 0 3551629 0 0 0 0 0 0 xen-percpu-ipi resched1 328: 0 77823 0 0 0 0 0 0 xen-percpu-ipi spinlock1 329: 0 13784021 0 0 0 0 0 0 xen-percpu-virq timer1 330: 730435 0 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle0 331: 0 0 0 0 0 0 0 0 xen-percpu-virq debug0 332: 39649 0 0 0 0 0 0 0 xen-percpu-ipi callfunc0 333: 3607120 0 0 0 0 0 0 0 xen-percpu-ipi resched0 334: 348740 0 0 0 0 0 0 0 xen-percpu-ipi spinlock0 335: 89912004 0 0 0 0 0 0 0 xen-percpu-virq timer0 NMI: 0 0 0 0 0 0 0 0 Interrupciones no enmascarables LOC: 0 0 0 0 0 0 0 0 Interrupciones locales del temporizador SPU: 0 0 0 0 0 0 0 0 Interrupciones espurias PMI: 0 0 0 0 0 0 0 0 Interrupciones de supervisión del rendimiento IWI: 0 0 0 0 0 0 0 0 Interrupciones de trabajo IRQ RES: 3607120 3551629 3422476 3802992 3482146 3468144 5374762 3236015 Reprogramación de interrupciones CAL: 770084 489287 952799 544546 919884 343765 863201 373596 Interrupciones de llamadas de función TLB: 0 0 0 0 0 0 0 0 derribos TLB TRM: 0 0 0 0 0 0 0 0 Interrupciones de eventos térmicos THR: 0 0 0 0 0 0 0 0 Umbral de interrupciones APIC MCE: 0 0 0 0 0 0 0 0 Excepciones de verificación de máquina MCP: 0 0 0 0 0 0 0 0 Encuestas de verificación de máquinas ERR: 0 SIG: 0
linux
ubuntu
performance-tuning
high-load
interrupts
Alexander Gladysh
fuente
fuente
eth1
?Respuestas:
Mira en el
/proc/irq/283
directorio. Hay unsmp_affinity_list
archivo que muestra qué CPU obtendrán la interrupción 283. Para usted, este archivo probablemente contiene "0" (ysmp_affinity
probablemente contiene "1").Puede escribir el rango de CPU en el
smp_affinity_list
archivo:O puede escribir una máscara de bits, donde cada bit corresponde a una CPU, para
smp_affinity
:Sin embargo, se sabe que irqbalance tiene su propia idea de la afinidad que debe tener cada interrupción, y podría revertir sus actualizaciones. Por lo tanto, es mejor si simplemente desinstala irqbalance por completo. O al menos deténgalo y desactívelo para que no se reinicie.
Si incluso sin irqbalance se vuelve extraño
smp_affinity
por la interrupción 283 después de un reinicio, deberá actualizar manualmente la afinidad de la CPU en uno de sus scripts de inicio.fuente
irqbalance
Ya se está ejecutando. Tal vez no está configurado correctamente? ¿Cómo verificar eso?/proc/irq/283/smp_affinity
tiene01
en él ahora (nadie ha cambiado esas cosas en esta máquina a lo mejor de mi conocimiento, por lo que esto debe ser el sistema predeterminado).irqbalance
(víaENABLED=0
adentro/etc/default/irqbalance
) no ayuda. Después de reiniciarirqbalance
esstop/waiting
, pero/proc/irq/283/smp_affinity
sigue siendo01
.Si tiene el modelo correcto de Intel NIC, puede mejorar significativamente el rendimiento.
Para citar el primer párrafo:
Consulte: Asignación de interrupciones a núcleos de procesador mediante un controlador Ethernet Intel® 82575/82576 o 82598/82599
fuente
En realidad , se recomienda, especialmente cuando se trata de procesos repetitivos de corta duración, que todas las interrupciones generadas por una cola de dispositivo sean manejadas por la misma CPU, en lugar del equilibrio de IRQ y, por lo tanto, verá un mejor rendimiento si una sola CPU maneja la interrupción eth1 *** excepción proporcionada a continuación
La fuente, vinculada anteriormente, es del Simposio de Linux y le recomiendo que lea los dos párrafos sobre SMP IRQ Affinity porque lo convencerá más efectivamente que esta publicación.
¿Por qué?
Recuerde que cada procesador tiene su propia memoria caché además de poder acceder a la memoria principal, consulte este diagrama . Cuando se dispara una interrupción, el núcleo de la CPU tendrá que buscar las instrucciones para manejar la interrupción desde la memoria principal, lo que lleva mucho más tiempo que si las instrucciones estuvieran en el caché. Una vez que un procesador ejecuta una tarea, tendrá esas instrucciones en la memoria caché. Ahora, digamos que el mismo núcleo de la CPU maneja la misma interrupción casi todo el tiempo, la función del controlador de interrupciones probablemente no saldrá del caché del núcleo de la CPU, lo que aumentará el rendimiento del kernel.
Alternativamente, cuando IRQ está equilibrado, puede asignar la interrupción para ser manejada constantemente por diferentes CPU, entonces el nuevo núcleo de la CPU probablemente no tendrá la función de manejo de interrupciones en el caché, y se requerirá mucho tiempo para obtener el manejador adecuado de main memoria.
Excepción : si rara vez usa la interrupción eth1, lo que significa que pasa el tiempo suficiente para que el caché se sobrescriba al realizar otras tareas, lo que significa que tiene datos que provienen de esa interfaz de forma intermitente con largos períodos intermedios ... entonces lo más probable es que no vea estos beneficios porque son cuando usas un proceso en alta frecuencia.
Conclusión
Si su interrupción ocurre con mucha frecuencia, entonces solo enlace esa interrupción para ser manejada por una CPU específica solamente. Esta configuración vive en
o
Vea el último párrafo en la sección de afinidad SMP IRQ de la fuente vinculada anteriormente, tiene instrucciones.
Alternativamente
Puede cambiar la frecuencia con la que se activa el indicador de interrupción aumentando el tamaño de MTU (tramas gigantes) si la red lo permite o cambiar para que se active el indicador después de recibir una mayor cantidad de paquetes en lugar de en cada paquete O cambiar el tiempo de espera, así que aumenta la interrupción después de un cierto período de tiempo. Tenga cuidado con la opción de tiempo porque el tamaño de su búfer podría estar lleno antes de que se agote el tiempo. Esto se puede hacer utilizando la herramienta ethtool que se describe en la fuente vinculada.
esta respuesta se acerca a la longitud en que la gente no la leerá, así que no entraré en muchos detalles, pero dependiendo de su situación, hay muchas soluciones ... verifique la fuente :)
fuente