Configuración de hilos basada en no. de núcleos de CPU


Escenario: Tengo una aplicación de ejemplo y tengo 3 configuraciones diferentes del sistema -

- 2 core processor, 2 GB RAM, 60 GB HHD,
- 4 core processor, 4 GB RAM, 80 GB HHD,
- 8 core processor, 8 GB RAM, 120 GB HHD

Con el fin de explotar eficazmente las capacidades H/W para mi aplicación, deseo configurar el no. de hilos a nivel de aplicación. Sin embargo, deseo hacer esto solo después de una comprensión profunda de las capacidades del sistema.

Podría haber alguna manera(system/modus/tool) de determinar la destreza del sistema con referencia a los números max y min. de hilos podría servir de manera óptima y sin ninguna pérdida de eficiencia y rendimiento. De esta manera, podría configurar solo aquellos valores para mi aplicación que harán justicia completa y lograr el mejor rendimiento para la configuración de hardware respectiva.

Edited1: Podría alguien por favor aconsejar cualquier lectura sobre cómo establecer una línea de base para una configuración de h/w en particular.

Edited2: Para hacerlo más directo-Deseo aprender / saber acerca de cualquier recurso / write-up que pueda leer para obtener un poco de comprensión sobre la CPU gestión de hilos a nivel general / holístico.

Author: Santosh, 2012-12-12

8 answers

El número óptimo de subprocesos a usar depende de varios factores, pero principalmente el número de procesadores disponibles y el uso intensivo de cpu de sus tareas. Java Concurrency in Practice propone la siguiente fórmula formal para estimar el número óptimo de subprocesos:

N_threads = N_cpu * U_cpu * (1 + W / C)

Donde:

  • N_threads es el número óptimo de hilos
  • N_cpu es el número de prcessores, que puede obtener de Runtime.getRuntime().availableProcessors();
  • U_cpu es la utilización de la CPU de destino (1 si desea utilizar todos los recursos disponibles)
  • W / C es la relación entre el tiempo de espera y el tiempo de cómputo (0 para tareas vinculadas a la CPU, tal vez 10 o 100 para tareas de E/S lentas)

Así que, por ejemplo, en un escenario limitado a CPU, tendría tantos subprocesos como CPU (algunos abogan por usar ese número + 1, pero nunca he visto que haya hecho una diferencia significativa).

Para un proceso de E / S lento, por ejemplo un rastreador web, W / C podría ser 10 si descargar una página es 10 veces más lento que procesarla, en qué caso usando 100 hilos sería útil.

Tenga en cuenta, sin embargo, que hay un límite superior en la práctica (el uso de 10.000 hilos generalmente no acelerará las cosas, y probablemente obtendría un error OutOfMemoryError antes de que pueda iniciarlos todos de todos modos con la configuración de memoria normal).

Esta es probablemente la mejor estimación que puede obtener si no sabe nada sobre el entorno en el que se ejecuta su aplicación. Perfilar su aplicación en producción podría permitirle afinar la configuración.

Aunque no está estrictamente relacionado, también podría interesarle la ley de Amdahl, que tiene como objetivo medir la velocidad máxima que puede esperar de paralelizar un programa.

 60
Author: assylias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-30 08:57:11

Mi recomendación es proporcionar conmutadores de configuración y línea de comandos para asignar el número de subprocesos por máquina. Utilice una heurística basada en el tiempo de ejecución.getRuntime().availableProcessors() como se indica en otras respuestas aquí, en casos en los que el usuario/administrador no ha configurado explícitamente la aplicación de manera diferente. I fuertemente recomienda no adivinar el hilo a núcleo basado en heurística exclusiva, por varias razones:

  • La mayoría del hardware moderno se está moviendo hacia tipos cada vez más ambiguos de "subprocesos de hardware": los modelos SMT como el Hyperthreading de Intel y los módulos de cómputo de AMD complican las fórmulas (detalles a continuación), y consultar esta información en tiempo de ejecución puede ser difícil.

  • La mayoría del hardware moderno tiene una función turbo que escala la velocidad en función de los núcleos activos y la temperatura ambiente. A medida que mejora la tecnología turbo, el rango de velocidad (ghz) crece. Algunos chips Intel y AMD recientes pueden variar de 2.6 ghz (todos los núcleos activos) a 3.6 ghz (núcleo único/doble active), que combinado con SMT puede significar que cada hilo obtenga un rendimiento efectivo de 1.6 ghz - 2.0 ghz en el diseño anterior. Actualmente no hay forma de consultar esta información en tiempo de ejecución.

  • Si no tiene una garantía sólida de que su aplicación será el único proceso que se ejecuta en los sistemas de destino, entonces consumir ciegamente todos los recursos de la cpu puede no complacer al usuario o al administrador del servidor (dependiendo de si el software es una aplicación de usuario o una aplicación de servidor).

No hay una forma robusta de saber lo que está pasando dentro del resto de la máquina en tiempo de ejecución, sin reemplazar todo el sistema operativo con su propio núcleo multitarea en casa. Su software puede intentar hacer conjeturas informadas consultando procesos y observando las cargas de CPU y demás, pero hacerlo es complicado y la utilidad se limita a tipos específicos de aplicaciones (de las cuales la suya puede calificar), y generalmente se beneficia o requiere niveles de acceso elevados o privilegiados.

  • Moderno los escáneres de virus hoy en día funcionan estableciendo una bandera de prioridad especial proporcionada por los sistemas operativos modernos, por ejemplo. dejan que el sistema operativo les diga cuando"el sistema está inactivo". El sistema operativo basa su decisión en algo más que la carga de la CPU: también considera la entrada del usuario y las banderas multimedia que pueden haber sido configuradas por reproductores de películas, etc. Esto está bien para tareas en su mayoría inactivas, pero no es útil para una tarea intensiva de cpu como la suya.

  • Las aplicaciones de computación doméstica distribuida (BOINC, Folding@Home, etc.) funcionan consultando los procesos en ejecución y la CPU del sistema se cargan periódicamente, quizás una vez cada segundo o medio segundo. Si se detecta carga en procesos que no pertenecen a la aplicación para varias consultas seguidas, la aplicación suspenderá el cálculo. Una vez que la carga se reduce para un cierto número de consultas, se reanuda. Se requieren múltiples consultas porque las lecturas de carga de la CPU son notorias por picos breves. Todavía hay advertencias: 1. Todavía se anima a los usuarios a reconfigurar manualmente BOINC para adaptarse a las especificaciones de su máquina. 2. si BOINC se ejecuta sin privilegios de administrador, entonces no será consciente de los procesos iniciados por otros usuarios (incluidos algunos procesos de servicio), por lo que puede competir injustamente con aquellos por los recursos de CPU.

En cuanto a SMT (HyperThreading, Compute Modules):

La mayoría de los SMT reportarán como núcleos de hardware o subprocesos en estos días, lo que generalmente no es bueno porque pocas aplicaciones funcionan de manera óptima cuando se escalan a través de cada núcleo en un sistema SMT. Para empeorar las cosas, preguntar si un núcleo es compartido (SMT) o dedicado a menudo no produce los resultados esperados. En algunos casos, el sistema operativo en sí simplemente no lo sabe (Windows 7 desconoce el diseño del núcleo compartido de AMD Bulldozer, por ejemplo). Si puede obtener un recuento SMT confiable, entonces la regla general es contar cada SMT como medio hilo para las tareas que requieren un uso intensivo de la CPU, y como un hilo completo para las tareas en su mayoría inactivas. Pero en realidad, el peso de la SMT depende de qué tipo de computación está haciendo, y el objetivo arquitectura. Las implementaciones SMT de Intel y AMD se comportan casi opuestas entre sí, por ejemplo Intel Intel es fuerte en la ejecución de tareas cargadas con operaciones de enteros y ramificaciones en paralelo. AMD es fuerte en la ejecución SIMD y operaciones de memoria en paralelo.

En cuanto a las características de Turbo:

La mayoría de las CPU en estos días tienen un soporte Turbo incorporado muy efectivo que disminuye aún más el valor ganado al escalar en todos los núcleos del sistema. Peor aún, la función turbo es a veces basado tanto en la temperatura real del sistema como en las cargas de la CPU, por lo que el sistema de enfriamiento de la torre en sí afecta la velocidad tanto como lo hacen las especificaciones de la CPU. En un AMD A10 en particular (Bulldozer), por ejemplo, lo observé corriendo a 3.7 ghz en dos hilos. Cayó a 3.5 ghz cuando se inicia un tercer hilo, y a 3.4 ghz cuando se inicia un cuarto. Dado que también es una GPU integrada, se redujo hasta aproximadamente 3.0 ghz cuando cuatro subprocesos más la GPU estaban funcionando (la CPU A10 internamente da prioridad a la GPU en escenarios de alta carga); pero todavía podría reunir 3.6 ghz con 2 hilos y GPU activa. Dado que mi aplicación usaba CPU y GPU, este fue un descubrimiento crítico. Pude mejorar el rendimiento general al limitar el proceso a dos subprocesos vinculados a la CPU (los otros dos núcleos compartidos seguían siendo útiles, sirvieron como subprocesos de servicio de GPU able capaces de despertarse y responder rápidamente para enviar nuevos datos a la GPU, según sea necesario).

... pero al mismo tiempo, mi la aplicación en roscas 4x puede haber funcionado mucho mejor en un sistema con un dispositivo de enfriamiento de mayor calidad instalado. Todo es muy complicado.

Conclusión: No hay una buena respuesta, y debido a que el campo del diseño de CPU SMT/Turbo sigue evolucionando, dudo que haya una buena respuesta en el corto plazo. Cualquier heurística decente que formule hoy puede muy bien no producir resultados ideales mañana. Así que mi recomendación es: no pierdas mucho tiempo en ello. Áspero-conjetura algo basado en conteos del núcleo que se adapte a sus propósitos locales lo suficientemente bien, permitir que se anule por config/switch, y seguir adelante.

 15
Author: jstine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-24 18:29:14

Puede obtener el número de procesadores disponibles para la JVM de la siguiente manera:

Runtime.getRuntime().availableProcessors()

Sin embargo, calcular el número óptimo de subprocesos a partir del número de procesadores disponibles desafortunadamente no es trivial. Esto depende mucho de las características de la aplicación, por ejemplo, con una aplicación vinculada a la CPU que tiene más subprocesos que el número de procesadores tiene poco sentido, mientras que si la aplicación está principalmente vinculada a IO, es posible que desee usar más subprocesos. Usted también necesita tomar en cuenta si otros procesos intensivos en recursos se están ejecutando en el sistema.

Creo que la mejor estrategia sería decidir el número óptimo de subprocesos empíricamente para cada una de las configuraciones de hardware, y luego usar estos números en su aplicación.

 14
Author: Gustav Grusell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-12 07:56:30

Estoy de acuerdo con las otras respuestas aquí que recomiendan un enfoque de mejor conjetura, y proporcionar configuración para sobreescribir los valores predeterminados.

Además, si su aplicación es particularmente intensiva en CPU, es posible que desee buscar en "anclar" su aplicación a procesadores particulares.

Usted no dice cuál es su sistema operativo principal, o si está soportando múltiples sistemas operativos, pero la mayoría tiene alguna forma de hacer esto. Linux, por ejemplo, tiene conjunto de tareas.

Un enfoque común es evitar CPU 0 (siempre utilizado por el sistema operativo), y establecer la afinidad de cpu de su aplicación a un grupo de CPU que están en el mismo socket.

Mantener los subprocesos de la aplicación lejos de la cpu 0 (y, si es posible, lejos de otras aplicaciones) a menudo mejora el rendimiento al reducir la cantidad de conmutación de tareas.

Mantener la aplicación en un socket puede aumentar aún más el rendimiento al reducir la invalidación de caché a medida que los hilos de la aplicación cambian entre cpus.

Al igual que con todo lo demás, esto depende en gran medida de la arquitectura de la máquina en la que se está ejecutando, así como de qué otras aplicaciones se están ejecutando.

 4
Author: GreyBeardedGeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-25 01:26:00

Use la herramienta VisualVM para monitorear subprocesos.Primero cree subprocesos mínimos en el programa y vea su rendimiento.Luego aumente el número de hilos dentro del programa y nuevamente analice su rendimiento.Que esto te ayude.

 2
Author: abishkar bhattarai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-24 15:23:21

Utilizo este script Python aquí para determinar el número de núcleos (y memoria, etc.) para lanzar mi aplicación Java con parámetros óptimos y ergonomía. Plataforma en Github

Funciona así: Escribe un script python que llame a getNumberOfCPUCores() en el script anterior para obtener el número de núcleos, y getSystemMemoryInMB() para obtener la RAM. Puede pasar esa información a su programa a través de argumentos de línea de comandos. Su programa puede utilizar el número apropiado de hilos basado en el número de núcleo.

 1
Author: goblinjuice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-25 06:39:43

Crear un subproceso a nivel de aplicación es bueno y en un procesador multinúcleo se ejecutan subprocesos separados en núcleos para mejorar performance.So para utilizar la potencia de procesamiento del núcleo, es la mejor práctica implementar el roscado.

Lo que pienso:

  1. En un momento solo 1 hilo de un programa se ejecutará en 1 núcleo.
  2. La misma aplicación con 2 thread se ejecutará en el medio tiempo en 2 core.
  3. La misma aplicación con 4 Subprocesos se ejecutará más rápido en 4 núcleo.

Así que la aplicación que está desarrollando debe tener el nivel de subproceso

El tiempo de ejecución del subproceso es administrado por el sistema operativo y es una actividad altamente impredecible. El tiempo de ejecución de la CPU se conoce como corte de tiempo o cuántica. Si creamos más y más subprocesos, el sistema operativo gasta una fracción de este segmento de tiempo en decidir qué subproceso va primero, reduciendo así el tiempo de ejecución real que obtiene cada subproceso. En otras palabras, cada thread hará menos trabajo si hay un gran número de hilos en cola.

Lee esto para saber cómo utilizar realmente el contenido.Fantastic de cpu core. csharp-codesamples.com/2009/03/threading-on-multi-core-cpus /

 1
Author: Vaibs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-26 09:17:27

Sin embargo, calcular el número óptimo de subprocesos a partir del número de procesadores disponibles desafortunadamente no es trivial. Esto depende mucho de las características de la aplicación, por ejemplo, con una aplicación vinculada a la CPU que tiene más subprocesos que el número de procesadores tiene poco sentido, mientras que si la aplicación está principalmente vinculada a IO, es posible que desee usar más subprocesos. También debe tener en cuenta si otros procesos intensivos en recursos se están ejecutando en el sistema.

 1
Author: user3118709,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 04:25:39