2011-05-24 6 views
6

Tenemos varios programas de estilo de "canalización" sensibles a la latencia que tienen una degradación de rendimiento mensurable cuando se ejecutan en un kernel Linux frente a otro. En particular, vemos un mejor rendimiento con el kernel 2.6.9 CentOS 4.x (RHEL4) y un peor rendimiento con el kernel 2.6.18 de CentOS 5.x (RHEL5).Diferencias de programación de hilos de Linux en sistemas multi-core?

Por "canalización", me refiero a uno que tiene múltiples hilos. Los hilos mutiple funcionan en datos compartidos. Entre cada hilo, hay una cola. Entonces, el subproceso A obtiene datos, ingresa Qab, el subproceso B extrae de Qab, procesa algo, luego presiona Qbc, tira C de Qbc, etc. Los datos iniciales son de la red (generados por un tercero).

Básicamente, medimos el tiempo desde que se reciben los datos hasta cuando el último hilo realiza su tarea. En nuestra aplicación, vemos un aumento de entre 20 y 50 microsegundos al pasar de CentOS 4 a CentOS 5.

He utilizado algunos métodos de creación de perfiles de nuestra aplicación, y he determinado que la latencia agregada en CentOS 5 proviene de operaciones de cola (en particular, reventado).

Sin embargo, puedo mejorar el rendimiento en CentOS 5 (para ser lo mismo que CentOS 4) mediante el uso del conjunto de tareas para vincular el programa a un subconjunto de los núcleos disponibles.

Me parece que, entre CentOS 4 y 5, hubo algún cambio (presumiblemente en el kernel) que provocó que los hilos se programaran de manera diferente (y esta diferencia no es óptima para nuestra aplicación).

Aunque puedo "resolver" este problema con taskset (o en código a través de sched_setaffinity()), mi preferencia es no tener que hacer esto. Espero que haya algún tipo de parámetro optimizable del kernel (o quizás una colección de parámetros optimizables) cuyo valor por defecto haya cambiado entre versiones.

¿Alguien tiene alguna experiencia con esto? Tal vez algunas áreas más para investigar?

Actualización: En este caso particular, el problema se resolvió mediante una actualización del BIOS del proveedor del servidor (Dell). Me saqué el pelo bastante tiempo en este caso. Hasta que volví a lo básico y verifiqué las actualizaciones de BIOS de mi proveedor. Sospechosamente, una de las actualizaciones decía algo así como "mejorar el rendimiento en el modo de máximo rendimiento". Una vez que actualicé el BIOS, CentOS 5 fue más rápido, hablando en términos generales, pero particularmente en mis pruebas de cola y las ejecuciones de producción reales.

Respuesta

1

Hmm .. si el tiempo necesario para una operación de pop() de una cola productor-consumidor está haciendo una diferencia significativa en el rendimiento general de su aplicación, sugeriría que la estructura de sus hilos/flujo de trabajo no es óptima , algun lado . A menos que haya una gran cantidad de disputas en las colas, me sorprendería que cualquier PC queue push/pop en cualquier SO moderno requiera más de un μS o más, incluso si la cola usa bloqueos de kernel en un clásico. - cómo hacer una cola de PC limitada con la forma de tres semáforos.

¿Puede usted acaba de absorber la funcionalidad de la rosca/s que hacer el menor trabajo en los que lo hacen la mayoría, lo que reduce el número de push/pop por elemento de trabajo total que fluye a través de su sistema?

+0

Las operaciones de dequeueing solo tienen un impacto en el rendimiento en el caso más lento, es decir, el nuevo kernel RHEL5. Basado en mis experimentos, mi mejor explicación para esto es que los diferentes hilos están programados en núcleos de tal manera que se pierden los beneficios de caché. Olvidé mencionar que mi máquina tiene paquetes duales de CPU de cuatro núcleos. Intuitivamente, si hay una cola compartida entre dos subprocesos programados en los dos CPU _packages_, el rendimiento será abismal. Pero, esto es solo una suposición, de ahí la pregunta. :) – Matt

+0

Ya veo. Ahora que lo mencionas, recuerdo haber rellenado deliberadamente un objeto de comunicación entre subprocesos para garantizar que dos instancias no pudieran estar en la misma línea de caché. Supongo que las cosas se ponen aún más sombrías si están involucrados dos paquetes discretos :( –

+0

Sí, no sé cuántos datos hay en las clases entre cadenas/struct/lo que sea, pero puedes crear un conjunto de ellos al inicio, asegurándote de que su tamaño/s es, por ejemplo, 4k y en un límite de página, lo que debería reducir el enjuague de caché, ya que no es necesario que dos núcleos tengan que operar en la misma página de datos. –

1

El programador de Linux ha sido un área intensa de cambio y contención a lo largo de los años. Es posible que desee probar un kernel muy reciente y probarlo. Sí, es posible que tengas que compilarlo tú mismo, será bueno para ti. También podría (cuando tenga un kernel más nuevo) querer considerar los diferentes procesos en diferentes contenedores con todo lo demás en uno adicional y ver si eso ayuda.

En cuanto a otras cosas aleatorias para probar, puede aumentar la prioridad de sus diversos procesos, agregar semántica en tiempo real (precaución, un programa con errores con privs en tiempo real puede privar al resto del sistema).

+0

Sin enlazar hilos a núcleos (es decir, taskset/sched_setaffinity()), las latencias empeoran _significativamente en una línea principal 2.6.39 kernel (de elrepo). Parece que, independientemente de los cambios que se realicen, es malo para nuestro tipo de programa. La verdadera cuestión de mi pregunta es, ¿cuáles son estos cambios? Y, a menos que se convierta en un experto en kernel, ¿hay alguna manera de entender los cambios del planificador desde un nivel conceptual? – Matt

+0

@Matt: AFAIK su mejor opción es revisar la lista de cambios de Kernel Newbies http://kernelnewbies.org/Linux26Changes para ver las discusiones sobre el rendimiento y los ajustes del programador, y estar preparado para probar muchos núcleos. –

Cuestiones relacionadas