2010-05-13 6 views
6

Ejecuto masivamente trabajos paralelos de informática científica en una computadora Linux compartida con 24 núcleos. La mayoría de las veces, mis trabajos son capaces de escalar a 24 núcleos cuando no se está ejecutando nada más en esta computadora. Sin embargo, parece que cuando se está ejecutando incluso un trabajo de subproceso único que no es el mío, mis trabajos de 24 hilos (que configuré para valores muy buenos) solo logran obtener ~ 1800% de CPU (usando notación de Linux). Mientras tanto, aproximadamente el 500% de los ciclos de la CPU (una vez más, utilizando la notación de Linux) están inactivos. ¿Alguien puede explicar este comportamiento y qué puedo hacer al respecto para obtener los 23 núcleos que no están siendo utilizados por otra persona?Linux 2.6.31 Programador y trabajos multiproceso

Notas:

  1. En caso de que sea relevante, he observado esto en versiones ligeramente diferentes del núcleo, aunque no puedo recordar lo que la parte superior de mi cabeza.

  2. La arquitectura de la CPU es x64. ¿Es posible que el hecho de que mis trabajos de 24 núcleos sean de 32 bits y los otros trabajos en los que estoy compitiendo con 64 bits es relevante?

Editar: Una cosa que acabo de notar es que subir hasta 30 hilos parece aliviar el problema hasta cierto punto. Me da hasta ~ 2100% de CPU.

+0

Reevaluando solo los procesos de efectos que usted conoce, si solo ejecuta un único proceso que genere n subprocesos ... bueno ... compite solo con un solo proceso. ¿Está disponible root/sudo en esta máquina? –

+0

¿Qué sucede si se reduce a 23 hilos, dejando un núcleo disponible para el otro trabajo? – caf

Respuesta

6

Es posible que esto se deba a que el planificador intenta mantener cada una de sus tareas ejecutándose en la misma CPU en la que se estaba ejecutando anteriormente (esto hace porque la tarea probablemente haya llevado su conjunto de trabajo a la memoria caché de esa CPU es "caché caliente").

He aquí algunas ideas que puede probar:

  • correr el doble de muchos hilos y cuando tenga núcleos;
  • Ejecute uno o dos subprocesos menos que sus núcleos;
  • Reduce el valor de /proc/sys/kernel/sched_migration_cost (quizás hasta cero);
  • Reducir el valor de /proc/sys/kernel/sched_domain/.../imbalance_pct abajo más cerca de 100.
0

Puede valer la pena utilizar mpstat (parte del paquete sysstat) para averiguar si tiene todas las CPUs inactivas mientras otras se utilizan por completo. Debería ofrecerle una vista más detallada de la utilización que top o vmstat: ejecute mpstat -P ALL para ver 1 línea por CPU.

Como experimento, puede intentar establecer la afinidad de la CPU en cada subproceso, de modo que cada una se vincule a una CPU individual; esto le permitiría ver cómo es el rendimiento si no permite que el planificador kernel decida en qué CPU está programada una tarea. No es una buena solución permanente, pero si ayuda mucho, te da una idea de dónde falta el planificador.

+0

Lamentablemente no tengo privilegios de administrador y sysstat no está instalado. – dsimcha

+1

No es difícil construir sysstat desde la fuente. –

2

¿Sus hilos tienen que sincronizarse? Si es así, puede tener el siguiente problema:

Supongamos que tiene un sistema de 4 cpu y un trabajo de 4 hilos. Cuando se ejecutan solos, los hilos se abren en abanico para usar los 4 núcleos y el uso total es casi perfecto (lo llamaremos 400%).

Si agrega un trabajo de interferencia de una sola hebra, el planificador puede colocar 2 de sus subprocesos en la misma CPU. Esto significa que 2 de sus subprocesos ahora se ejecutan a la mitad de su ritmo normal (simplificación dramática), y si sus subprocesos necesitan sincronizarse periódicamente, el progreso de su trabajo puede verse limitado por el subproceso más lento, que en este caso se está ejecutando en la mitad de la velocidad normal. Vería una utilización de solo 200% (de su trabajo ejecutando 4x 50%) más 100% (el trabajo que interfiere) = 300%.

Del mismo modo, si supone que el trabajo de interferencia solo utiliza el 25% del tiempo de un procesador, puede ver uno de sus hilos y el interferer en la misma CPU. En ese caso, el hilo más lento corre a una velocidad normal de 3/4, lo que hace que la utilización total sea del 300% (4x 75%) + 25% = 325%. Juega con estos números y no es difícil encontrar algo similar a lo que estás viendo.

Si ese es el problema, ciertamente puede jugar con las prioridades para dar tareas no deseadas solo pequeñas fracciones de CPU disponibles (supongo que las demoras de E/S no son un factor). O, como ha encontrado, intente aumentar los hilos para que cada CPU tenga, digamos, 2 hilos, menos algunos para permitir las tareas del sistema. De esta forma, un sistema de 24 núcleos podría funcionar mejor con, digamos, 46 subprocesos (lo que siempre deja la mitad del tiempo de 2 núcleos disponible para las tareas del sistema).

+0

Por supuesto, la sugerencia de caf de 23 hilos probablemente sea mejor que mi sugerencia de 46 hilos como una forma de obtener un 2300% de utilización. –

0

¿Cree que el cuello de botella está en su aplicación o algoritmo de planificación del kernel? Antes de comenzar a ajustar los parámetros de programación, le sugiero que intente ejecutar una aplicación sencilla de subprocesos múltiples para ver si muestra el mismo comportamiento que su aplicación.

// COMPILE WITH: gcc threads.c -lpthread -o thread 
#include <pthread.h> 
#define NUM_CORES 24 

void* loop_forever(void* argument) { 
    int a; 
    while(1) a++; 
} 

void main() { 
    int i; 
    pthread_t threads[NUM_CORES]; 

    for (i = 0; i < NUM_CORES; i++) 
     pthread_create(&threads[i], 0, loop_forever, 0); 

    for (i = 0; i < NUM_CORES; i++) 
     pthread_join(threads[i], 0); 
} 
1

¿Sus hilos se comunican entre sí?

Intente vincular manualmente cada hilo a la CPU, con sched_setaffinity o pthread_setaffinity_np. El programador puede ser bastante tonto cuando trabaja con muchos hilos relacionados.

Cuestiones relacionadas