Pregunta

corro puestos de trabajo de computación científica masivamente paralelo en un equipo Linux compartido con 24 núcleos. La mayoría de las veces mis trabajos son capaces de escalar a 24 núcleos cuando nada más se está ejecutando en este equipo. Sin embargo, parece que cuando un solo empleo de un solo roscada que no es el mío está en marcha, mis trabajos de 24 hilos (que yo pongo para valores altos agradables), sólo pude conseguir ~ 1,800% de la CPU (usando la notación de Linux). Mientras tanto, aproximadamente 500% de los ciclos de CPU (de nuevo, usando la notación Linux) son inactivo. ¿Puede alguien explicar este comportamiento y lo que puede hacer al respecto para obtener todos los 23 núcleos que no están siendo utilizados por otra persona?

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 del todo posible que el hecho de que mis trabajos de 24 núcleos son de 32 bits y los otros puestos de trabajo que estoy compitiendo w / son de 64 bits es relevante?

Edit: Una cosa que me he dado cuenta de que está subiendo a 30 hilos parece aliviar el problema hasta cierto punto. Me pone hasta ~ 2100% de la CPU.

¿Fue útil?

Solución

Es posible que esto es causado por el planificador tratando de mantener cada una de las tareas que se ejecutan en la misma CPU que fue previamente ejecutando en (no hace esto porque la tarea es probable que haya traído su conjunto de trabajo en la caché de que la CPU - es "caché caliente").

Aquí hay algunas ideas que puede probar:

  • Ejecutar el doble de hilos a medida que tienen núcleos;
  • Ejecutar uno o dos hilos menos de lo que tienen núcleos;
  • Reducir el valor de /proc/sys/kernel/sched_migration_cost (tal vez a cero);
  • reducir el valor de /proc/sys/kernel/sched_domain/.../imbalance_pct abajo más cerca de 100.

Otros consejos

¿Tienen que sincronizar los hilos? Si es así, usted podría tener el siguiente problema:

Supongamos que tiene un sistema de 4 CPU, y un trabajo de 4 hilos. Cuando se ejecuta solo, las discusiones se abren en abanico para utilizar los 4 núcleos y el uso total es casi perfecto (Llamaremos a este 400%).

Si se agrega un trabajo interfiriendo de un solo subproceso, el programador puede colocar 2 de sus hilos en la misma CPU. Esto significa que 2 de los hilos se encuentran hoy en efectivamente la mitad de su ritmo normal (simplificación dramática), y si los hilos necesitan sincronizar periódicamente, el progreso del trabajo de pueden estar limitadas por el hilo más lento, que en este caso se está ejecutando en velocidad normal media. Que se vería la utilización de sólo el 200% (de su trabajo en ejecución 4x 50%) más el 100% (el trabajo interfiriendo) = 300%.

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

Si ese es el problema, que sin duda puede jugar con las prioridades para dar tareas no deseadas sólo pequeñas fracciones de CPU disponible (estoy suponiendo E / S retrasos no son un factor). O, como lo has encontrado, intenta aumentar hilos para que cada CPU tiene, digamos, 2 hilos, menos unos pocos para permitir tareas del sistema. De este modo, un sistema de 24 elementos esenciales pudieran funcionar mejor con, digamos, 46 hilos (que siempre deja la mitad de tiempo de 2 núcleos disponible para las tareas del sistema).

¿Sus hilos se comunica con los demás?

Trate de manualmente unen cada hilo a la CPU, con sched_setaffinity o pthread_setaffinity_np. Planificador puede ser bastante tonto cuando se trabaja con una gran cantidad de temas relacionados.

Podría ser útil para uso mpstat (parte del paquete sysstat ) con la figura si tiene CPUs enteras sentados sin hacer nada mientras que otros se utilizan plenamente. Se le debe dar una visión más detallada de la utilización de la parte superior o vmstat:. mpstat -P ALL correr para ver la línea 1 por CPU

A modo de experimento, se podría tratar de establecer la afinidad de la CPU en cada hilo de tal manera que cada uno está obligado a una CPU individual; esto permitirá ver lo que el rendimiento es como si no deja que el programador del núcleo de la CPU decidir qué tarea está programada para el. No es una buena solución permanente, pero si ayuda mucho que te da una idea de donde el programador está a la altura.

¿Cree que el cuello de botella está en su aplicación o algoritmo de planificación del kernel? Antes de empezar a ajustar parámetros de programación, le sugiero que intenta ejecutar una sencilla aplicación multi-hilo para ver si presenta el mismo comportamiento como 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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top