10

Di corro un proceso simple de un solo subproceso como la siguiente:¿Por qué un único proceso con hilos se ejecuta en varios procesadores/núcleos?

public class SirCountALot { 
    public static void main(String[] args) { 
     int count = 0; 
     while (true) { 
      count++; 
     } 
    } 
} 

(Esto es Java, porque eso es lo que estoy familiarizado, pero sospecho que en realidad no importa)

Tengo un procesador i7 (4 núcleos, o 8 contando hyperthreading), y estoy ejecutando Windows 7 de 64 bits, así que encendí Sysinternals Process Explorer para ver el uso de la CPU, y como esperaba veo que está usando alrededor del 20% de toda la CPU disponible.

Graph showing 20% CPU usage across all cores

Pero cuando activar y desactivar la opción de mostrar 1 gráfico por CPU, veo que en vez de 1 de los 4 "núcleos" siendo utilizado, el uso de la CPU se extiende por todo los núcleos:

Graph showing erratic CPU usage on each core totaling around 20% usage

En lugar de lo que esperaría es 1 núcleo máximo, pero esto solo ocurre cuando establezco la afinidad para el proceso a un solo núcleo.

Graph showing most of recent CPU usage to be confined to first core

¿Por qué la carga de trabajo divididos sobre los núcleos separados? ¿No dividiría la carga de trabajo entre varios núcleos con el almacenamiento en caché o incurriría en otras penalizaciones de rendimiento?

¿Es por la simple razón de evitar el sobrecalentamiento de un núcleo? ¿O hay alguna razón más profunda?

Edit: Soy consciente de que el sistema operativo es responsable de la programación, pero quiero saber por qué "molesta". Sin duda, desde un punto de vista ingenuo, pegar un (en su mayoría *) proceso de un único subproceso a 1 núcleo es el más simple & manera más eficiente de ir?

* Me dicen su mayoría un único subproceso porque hay múltiples theads aquí, pero sólo 2 de ellos están haciendo nada:

Screenshot showing number of threads from Eclipse Screenshot showing number of threads in Process Explorer process properties

+2

Pequeño nitpick; decir que este es un proceso de un solo subproceso no será correcto. JVM internamente genera múltiples hilos para fines de limpieza como finalizadores, recolectores de basura, etc. Es muy posible que para hacer un trabajo real por cada hilo, los hilos JVM se mapeen a hilos reales h/w, lo que de nuevo podría explicar la dispersión. –

+0

Supongo que Caspar significaba los hilos _non-daemon_. – Santosh

+0

@ SanjayT.Sharma Sí, simplifiqué un poco y probablemente debería haber dado un programa de ejemplo en un lenguaje no administrado;) Sin embargo, como dije, sospecho que no es la JVM la que está haciendo esto (y si está mapeando JVM -> hilos HW y que es responsable, ¿por qué la asignación está cambiando constantemente?) – Caspar

Respuesta

17

El sistema operativo es responsable de programar. Es libre de detener un hilo y volver a iniciarlo en otra CPU. Hará esto incluso si no hay nada más que la máquina esté haciendo.

El proceso se mueve alrededor de las CPU porque el sistema operativo no supone que haya ninguna razón para continuar ejecutando el subproceso en la misma CPU cada vez.

Por esta razón he escrito una biblioteca para bloquear los hilos a una CPU para que no se mueva y no sea interrumpida por otros hilos. Esto reduce la latencia y mejora el rendimiento, pero satura una CPU para ese hilo. Esto funciona para Linux, quizás puedas adaptarlo para Windows. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started

+0

Se interrumpe un proceso muchas veces por segundo. (100/s en Linux) Es más trabajo recordar dónde se estaba ejecutando un proceso por última vez e intentar asignar esa CPU con preferencia a cualquier otra, en su lugar, la asigna a la siguiente CPU libre. –

+0

Supongo que no estoy lo suficientemente claro; Soy consciente de que el sistema operativo realiza la programación, y pueden ver en el segundo gráfico que he establecido la afinidad para el proceso, por lo que solo utiliza el primer núcleo. Lo que quiero saber es * ¿por qué * el sistema operativo programa el único hilo "activo" sobre todos los núcleos disponibles? – Caspar

+0

La pregunta inversa es por qué seguir asignando un hilo a la misma CPU en lugar de simplemente asignarlo a la siguiente CPU libre (que es lo que hace) El uso de round robin funciona bien sin importar cuántas CPU están ocupadas. Asignar a la misma CPU cada vez podría dejar a una CPU muy ocupada (con dos subprocesos ejecutándose) mientras otras CPU están inactivas. –

1

yo también esperan que esto podría ser hecho a propósito por la CPU y el sistema operativo con el fin de tratar de repartir la carga térmica en el dado de la CPU ...

por lo que sería girar la (única/sola) hilo desde el núcleo hasta el núcleo.

Y es cierto que podría ser un argumento en contra de tratar de luchar contra esta demasiado duro (especialmente en lo que, en la práctica, a menudo se verá mejor mejoras simplemente seleccionando/mejora de la aplicación en sí de todos modos)

+0

Interesante. ¿Sabes que Windows/Linux hace esto con seguridad, o es una hipótesis? (También, bienvenido a stackoverflow:) – Leeor

+0

He visto esto claramente sucediendo en OSX y Windows. Esperaría lo mismo para Linux, pero nunca intenté verificarlo específicamente. – Camlin

Cuestiones relacionadas