2010-06-05 15 views
5

tengo mi propio programa de multiproceso C que escala en la velocidad sin problemas con el número de núcleos de CPU .. puedo correr con 1, 2, 3, etc y obtener hilos velocidad lineal ... hasta aproximadamente 5.5x velocidad en una CPU de 6 núcleos en una caja Ubuntu Linux.Linux por proceso límites de recursos - una profunda Red Hat Mystery

que tuvieron la oportunidad de ejecutar el programa en un extremo muy alto Sunfire X4450 con 4 procesadores Xeon de cuatro núcleos, que ejecutan Red Hat Enterprise Linux. Estaba esperando ansiosamente ver cuán rápido los 16 núcleos podían ejecutar mi programa con 16 hilos ... ¡Pero funciona a la misma velocidad que DOS hilos!

Mucho tirón de pelo y depuración más tarde, veo que mi programa realmente está creando todos los hilos, realmente se están ejecutando simultáneamente, pero los hilos en sí son más lentos de lo que deberían ser. ¡2 hilos se ejecutan aproximadamente 1.7 veces más rápido que 1, pero 3, 4, 8, 10, 16 hilos funcionan todos con solo 1.9x! Veo que todos los hilos se están ejecutando (no estancados o durmiendo), son lentos.

Para comprobar que el HARDWARE no tuvo la culpa, ejecuté DIECISÉIS copias de mi programa de forma independiente, simultáneamente. Todos corrieron a toda velocidad. Realmente hay 16 núcleos y realmente funcionan a toda velocidad y realmente hay suficiente RAM (de hecho, esta máquina tiene 64 GB y solo uso 1 GB por proceso).

lo tanto, mi pregunta es si hay alguna explicación del sistema operativo, tal vez algún límite de recursos por proceso que escala automáticamente la programación de subprocesos para mantener un proceso utilice acaparando la máquina.

Las pistas son:

  1. Mi programa no accede al disco o red. Es un CPU limitado. Su velocidad se escala linealmente en una sola caja de CPU en Ubuntu Linux con a hexacore i7 para 1-6 hilos. 6 hilos es efectivamente 6 veces más rápido.
  2. Mi programa nunca se ejecuta más rápido que 2 veces la aceleración en este 16 núcleos Sunfire caja Xeon, para cualquier número de hilos de 2-16.
  3. Ejecutando 16 copias de mi programa de un solo hilo ejecuta perfectamente, todas las 16 funcionan a la vez a a toda velocidad.
  4. arriba muestra 1600% de CPU asignadas./Proc/cpuinfo muestra los 16 núcleos funcionando a toda velocidad 2.9GHz (no baja frecuencia ralentí de 1,6 GHz)
  5. Hay 48 GB de memoria RAM libre, no está intercambiando.

¿Qué está pasando? ¿Hay alguna política de límite de CPU de proceso? ¿Cómo podría medirlo si es así? ¿Qué más podría explicar este comportamiento?

Gracias por sus ideas para resolver esto, la desaceleración gran misterio Xeon de 2010!

Respuesta

1

Mi conjetura inicial serían los cuellos de botella de memoria compartida. Por lo que dices, tu rendimiento es más o menos plano después de 2 CPU. Inicialmente culpas a Redhat, pero me gustaría saber qué pasa si instalas Ubuntu en el mismo hardware. Supongo, por supuesto, que está ejecutando núcleos SMP de 64 bits en ambas pruebas.

Probablemente no sea posible que la placa base alcanzaría su punto máximo en la utilización de 2 CPUs.Tienes otra máquina con múltiples núcleos que ha proporcionado un mejor rendimiento. ¿Tiene hyperthreading encendido con la nueva máquina? (¿Y cómo se compara esa respuesta con la máquina anterior?). ¿No estás, por casualidad, corriendo en un entorno virtualizado?

En general, su evidencia apunta a un cuello de botella ridículamente lento en alguna parte. Como dijiste, no estás vinculado a E/S, por lo que deja la CPU y la memoria. O algo está mal con el hardware, o algo está mal con el hardware. Pruebe uno cambiando el otro, y reducirá sus posibilidades rápidamente.

+0

La mayoría de esos puntos son EXCELENTES y son lo que miré primero. Pero el hecho de que 16 copias individuales se ejecuten a toda velocidad significa que no es un problema de CPU, memoria, hyperthreading o virtualización. Ahora estoy convencido de que no es un problema de programación, sino algo relacionado con el sistema operativo, pero no sé dónde buscar. La instalación de un nuevo sistema operativo obviamente sería una gran prueba, excepto que se trata de un servidor SunFire de $ 22,000 al que tengo acceso pero que no me pertenece. –

2

Investigue un poco sobre rlimit: es muy posible que el shell/usuario en el que se está ejecutando tenga algunos límites de recursos RH predeterminados o establecidos por el administrador.

0

Cuando vea este tipo de comportamiento de escala impar, especialmente si los problemas se ven con múltiples hilos, pero no los procesos múltiples, una cosa que empezar a buscar es el impacto de la contención de bloqueo y otras primitivas de sincronización, que pueden causar subprocesos que se ejecutan en diferentes procesadores para tener que esperar el uno del otro, lo que puede forzar a varios núcleos a vaciar su caché a la memoria principal.

Esto significa que la arquitectura de memoria comienza a entrar en juego, y eso será mucho más rápido cuando tenga 6 núcleos en una sola pieza de silicio que cuando coordine 4 procesadores por separado. Específicamente, la carcasa de una sola CPU probablemente no necesita golpear la memoria principal para operaciones de bloqueo: todo es probable que se maneje en el nivel de caché L3, permitiendo que la CPU continúe con las cosas mientras los datos se descargan a la memoria principal en el fondo .

Si bien espero que el OP haya perdido interés en la pregunta después de todo este tiempo (o tal vez ni siquiera tenga acceso al hardware), una forma de verificar esto sería ver si mejora la escala de hasta 4 hilos si la afinidad del proceso está configurada para bloquearlo en una sola CPU física. Aún mejor sería perfilar la aplicación para ver dónde está gastando su tiempo. A medida que cambia las arquitecturas y aumenta el número de núcleos, es cada vez más difícil adivinar dónde están los cuellos de botella, por lo que realmente necesita comenzar a medir cosas directamente, como en este ejemplo: http://postgresql.1045698.n5.nabble.com/Sun-Donated-a-Sun-Fire-T2000-to-the-PostgreSQL-community-td2057445.html

Cuestiones relacionadas