programming parallel computing book parallel-processing cpu

parallel processing - parallel - Número óptimo de hilos por núcleo



parallel programming book (13)

Digamos que tengo una CPU de 4 núcleos y quiero ejecutar algún proceso en el tiempo mínimo. El proceso es idealmente paralelizable, por lo que puedo ejecutar fragmentos de él en un número infinito de subprocesos y cada subproceso lleva la misma cantidad de tiempo.

Como tengo 4 núcleos, no espero ninguna aceleración ejecutando más subprocesos que núcleos, ya que un solo núcleo solo es capaz de ejecutar un solo subproceso en un momento dado. No sé mucho sobre hardware, así que esto es solo una conjetura.

¿Hay algún beneficio al ejecutar un proceso paralelo en más subprocesos que núcleos? En otras palabras, ¿mi proceso finalizará más rápido, más lento o en aproximadamente la misma cantidad de tiempo si lo ejecuto utilizando 4000 subprocesos en lugar de 4 subprocesos?


4000 hilos a la vez es bastante alto.

La respuesta es sí y no. Si está realizando una gran cantidad de I / O de bloqueo en cada subproceso, entonces sí, podría mostrar un aumento de velocidad significativo con hasta 3 o 4 subprocesos por núcleo lógico.

Sin embargo, si no está haciendo muchas cosas bloqueando, la sobrecarga adicional con el enhebrado solo lo hará más lento. Así que use un perfilador y vea dónde están los cuellos de botella en cada pieza posiblemente paralela. Si está realizando cálculos pesados, más de 1 subproceso por CPU no ayudará. Si está haciendo mucha transferencia de memoria, tampoco ayudará. Si está realizando una gran cantidad de E / S, como el acceso a disco o el acceso a Internet, sí, varios subprocesos ayudarán hasta cierto punto, o al menos harán que la aplicación sea más receptiva.


El ideal es 1 hilo por núcleo, siempre que ninguno de los hilos se bloquee.

Un caso en el que esto puede no ser cierto: hay otros subprocesos que se ejecutan en el núcleo, en cuyo caso más subprocesos pueden dar a su programa una mayor porción del tiempo de ejecución.


El rendimiento real dependerá de la cantidad de rendimiento voluntario que haga cada subproceso. Por ejemplo, si los subprocesos no hacen ninguna E / S en absoluto y no utilizan servicios del sistema (es decir, son 100% cpu), entonces 1 subproceso por núcleo es el óptimo. Si los subprocesos hacen algo que requiere esperar, entonces tendrás que experimentar para determinar el número óptimo de subprocesos. 4000 subprocesos incurrirían en una sobrecarga de programación significativa, por lo que probablemente tampoco sea óptimo.


Encontrará la cantidad de subprocesos que puede ejecutar en su máquina ejecutando el comando htop o ps que devuelve la cantidad de procesos en su máquina.

Puedes usar la página del manual sobre el comando ''ps''.

man ps

Si desea calcular el número de procesos de todos los usuarios, puede usar uno de estos comandos:

  1. ps -aux| wc -l
  2. ps -eLf | wc -l

Cálculo del número de un proceso de usuario:

  1. ps --User root | wc -l

Además, puedes usar "htop" [Reference] :

Instalación en Ubuntu o Debian:

sudo apt-get install htop

Instalación en Redhat o CentOS:

yum install htop dnf install htop [On Fedora 22+ releases]

Si desea compilar htop desde el código fuente, lo encontrará [Reference] .


Espero que esto tenga sentido, compruebe la CPU y la utilización de la memoria y ponga un valor de umbral. Si se cruza el valor de umbral, no permita crear un nuevo hilo, o permita ...


Estoy de acuerdo con la respuesta de @ Gonzalo. Tengo un proceso que no hace E / S, y aquí es lo que he encontrado:

Tenga en cuenta que todos los subprocesos funcionan en una matriz, pero distintos rangos (dos subprocesos no acceden al mismo índice), por lo que los resultados pueden diferir si han funcionado en diferentes arreglos.

La máquina 1.86 es un macbook air con un SSD. El otro mac es un iMac con un disco duro normal (creo que es de 7200 rpm). La máquina de Windows también tiene un disco duro de 7200 rpm.

En esta prueba, el número óptimo era igual al número de núcleos en la máquina.


La respuesta depende de la complejidad de los algoritmos utilizados en el programa. Se me ocurrió un método para calcular el número óptimo de hilos haciendo dos mediciones de los tiempos de procesamiento Tn y Tm para dos números arbitrarios de hilos ''n'' y ''m''. Para algoritmos lineales, el número óptimo de subprocesos será N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)).

Por favor, lea mi artículo sobre los cálculos del número óptimo para varios algoritmos: pavelkazenin.wordpress.com


Pensé que añadiría otra perspectiva aquí. La respuesta depende de si la pregunta es asumir una escala débil o una escala fuerte.

De Wikipedia :

Escalamiento débil: cómo varía el tiempo de la solución con la cantidad de procesadores para un tamaño de problema fijo por procesador.

Escalamiento fuerte: cómo varía el tiempo de solución con la cantidad de procesadores para un tamaño de problema total fijo.

Si la pregunta es asumir una escala débil, entonces la respuesta de @ Gonzalo es suficiente. Sin embargo, si la pregunta es asumir una escala fuerte, hay algo más que agregar. En una escala fuerte, está asumiendo un tamaño de carga de trabajo fijo, por lo que si aumenta el número de subprocesos, el tamaño de los datos en los que cada subproceso necesita trabajar disminuye. En las CPU modernas, los accesos a la memoria son caros y sería preferible mantener la localidad manteniendo los datos en cachés. Por lo tanto, se puede encontrar el número óptimo de subprocesos cuando el conjunto de datos de cada subproceso se ajusta a la memoria caché de cada núcleo (no voy a entrar en los detalles de discutir si se trata de caché L1 / L2 / L3 del sistema).

Esto es cierto incluso cuando el número de subprocesos supera el número de núcleos. Por ejemplo, suponga que hay 8 unidades arbitrarias (o AU) de trabajo en el programa que se ejecutarán en una máquina de 4 núcleos.

Caso 1: ejecute con cuatro subprocesos donde cada subproceso debe completar 2AU. Cada hilo tarda 10 segundos en completarse ( con una gran cantidad de errores de caché ). Con cuatro núcleos, la cantidad total de tiempo será 10s (10s * 4 hilos / 4 núcleos).

Caso 2: ejecutar con ocho subprocesos donde cada subproceso debe completar 1AU. Cada hilo solo toma 2 segundos (en lugar de 5 segundos debido a la cantidad reducida de errores de caché ). Con ocho núcleos, la cantidad total de tiempo será 4s (2s * 8 hilos / 4 núcleos).

He simplificado el problema y he ignorado los gastos generales mencionados en otras respuestas (por ejemplo, cambios de contexto), pero espero que comprenda que podría ser beneficioso tener un mayor número de subprocesos que el número de núcleos disponibles, dependiendo del tamaño de los datos. se trata de.


Punto de referencia.

Comenzaría a aumentar el número de subprocesos para una aplicación, comenzando en 1, y luego iría a algo así como 100, realizaría tres o cinco intentos para cada número de subprocesos y me crearía un gráfico de la velocidad de operación en función del número de subprocesos .

Debería que el caso de cuatro hilos sea óptimo, con leves incrementos en el tiempo de ejecución después de eso, pero tal vez no. Puede ser que su aplicación tenga un ancho de banda limitado, es decir, el conjunto de datos que está cargando en la memoria es enorme, está obteniendo muchas fallas de caché, etc., de manera que 2 subprocesos son óptimos.

No puedes saber hasta que pruebes.


Sé que esta pregunta es bastante antigua, pero las cosas han evolucionado desde 2009.

Hay dos cosas a tener en cuenta ahora: la cantidad de núcleos y la cantidad de subprocesos que pueden ejecutarse dentro de cada núcleo.

Con los procesadores Intel, el número de subprocesos se define mediante el Hyperthreading, que es solo 2 (cuando está disponible). ¡Pero Hyperthreading reduce el tiempo de ejecución en dos, incluso cuando no se utilizan 2 hilos! (es decir, 1 canalización compartida entre dos procesos: esto es bueno cuando se tienen más procesos, de lo contrario no es tan bueno. ¡Más núcleos son definitivamente mejores!)

En otros procesadores puede tener 2, 4 o incluso 8 hilos. Entonces, si tiene 8 núcleos, cada uno de los cuales admite 8 subprocesos, podría tener 64 procesos ejecutándose en paralelo sin cambio de contexto.

"Sin cambio de contexto" obviamente no es cierto si se ejecuta con un sistema operativo estándar que hará el cambio de contexto para todo tipo de cosas fuera de su control. Pero esa es la idea principal. ¡Algunos sistemas operativos le permiten asignar procesadores para que solo su aplicación tenga acceso / uso de dicho procesador!

Desde mi propia experiencia, si tiene mucha E / S, varios subprocesos es bueno. Si tiene un trabajo muy intensivo en memoria (lectura de origen 1, lectura de origen 2, cálculo rápido, escritura), tener más subprocesos no ayuda. Nuevamente, esto depende de la cantidad de datos que lea / escriba simultáneamente (es decir, si usa SSE 4.2 y lee valores de 256 bits, eso detiene a todos los subprocesos en sus pasos ... en otras palabras, 1 subproceso es probablemente mucho más fácil de implementar y probablemente casi tan rápido, si no realmente más rápido. Esto dependerá de su arquitectura de proceso y memoria, algunos servidores avanzados administran rangos de memoria separados para núcleos separados, por lo que los subprocesos separados serán más rápidos suponiendo que sus datos estén correctamente archivados ... arquitecturas, 4 procesos se ejecutarán más rápido que 1 proceso con 4 hilos.)


Si sus subprocesos no hacen E / S, sincronización, etc., y no hay nada más en ejecución, 1 subproceso por núcleo le dará el mejor rendimiento. Sin embargo eso es muy probable que no sea el caso. Por lo general, agregar más subprocesos ayuda, pero después de algún punto, causan cierta degradación del rendimiento.

No hace mucho, estaba haciendo pruebas de rendimiento en una máquina de 2 quad-core que ejecutaba una aplicación ASP.NET en Mono bajo una carga bastante decente. Jugamos con el número mínimo y máximo de subprocesos y, al final, descubrimos que para esa aplicación en particular en esa configuración particular, el mejor rendimiento era entre 36 y 40 subprocesos. Cualquier cosa fuera de esos límites funcionó peor. ¿Lección aprendida? Si yo fuera usted, probaría con un número diferente de hilos hasta que encuentre el número correcto para su aplicación.

Una cosa es segura: 4k hilos tomarán más tiempo. Eso es un montón de cambios de contexto.


Un ejemplo de muchos subprocesos ("grupo de subprocesos") frente a uno por núcleo es el de implementar un servidor web en Linux o en Windows.

Dado que los sockets se sondean en Linux, muchos subprocesos pueden aumentar la probabilidad de que uno de ellos encueste el socket correcto en el momento adecuado, pero el costo general de procesamiento será muy alto.

En Windows, el servidor se implementará utilizando los puertos de finalización de E / S (IOCP, IOCP), que harán que la aplicación se dirija a eventos: si una E / S completa, el sistema operativo inicia un subproceso en espera para procesarlo. Cuando el procesamiento se completa (generalmente con otra operación de E / S como en un par de solicitud-respuesta), el hilo regresa al puerto IOCP (cola) para esperar la siguiente finalización.

Si no se ha completado ninguna E / S, no se debe realizar ningún procesamiento ni se inicia ningún subproceso.

De hecho, Microsoft recomienda no más de un hilo por núcleo en las implementaciones de IOCP. Cualquier E / S puede estar conectada al mecanismo IOCP. Los IOC también pueden ser publicados por la aplicación, si es necesario.


hablando desde el punto de vista de la computación y la memoria (computación científica) 4000 hilos harán que la aplicación se ejecute muy lentamente. Parte del problema es una sobrecarga muy alta de cambio de contexto y muy probablemente una localidad de memoria muy pobre.

Pero también depende de su arquitectura. Desde donde escuché, se supone que los procesadores Niagara son capaces de manejar múltiples hilos en un solo núcleo utilizando algún tipo de técnica avanzada de canalización. Sin embargo no tengo experiencia con esos procesadores.