Formas de visualizar datos de eventos en busca de problemas de rendimiento

10

Estoy tratando de optimizar una aplicación MPI con un patrón de comunicación altamente asíncrono. Cada rango tiene una lista de cosas para calcular y envía mensajes según sea necesario si las entradas o salidas residen en un rango diferente. Además, cada rango está enhebrado (actualmente con un hilo de comunicación y 5 trabajadores).

He instrumentado el código con temporizadores en torno a las diferentes porciones críticas de rendimiento del código, lo que me da una lista de (inicio, fin, tipo) triples para cada hilo. Trazado de manera obvia, con el tiempo como eje horizontal, rango e hilo como vertical, y el color indicando lo que cada hilo está haciendo actualmente, obtengo una imagen como esta para 16 rangos con 6 hilos / rango:

Rango de Pentago e historia de hilos

Mi pregunta es: ¿cuáles son otras formas de visualizar estos datos que podrían ayudar a detectar problemas de rendimiento? ¿Alguien tiene un tipo de diagrama favorito que usan al perfilar aplicaciones asincrónicas?

Este conjunto de datos es limitado porque no conoce la estructura del flujo de datos, pero me gustaría obtener la mayor cantidad de información posible antes de intentar recopilar algo más complicado.

La imagen sin comprimir está aquí en caso de que alguien quiera mirar alrededor (no se pudo cargar a través de la ruta normal). Desafortunadamente, Firefox no lo acepta a pesar de que creo que es válido, posiblemente porque es simplemente demasiado grande.

Geoffrey Irving
fuente
Tuve bastantes problemas para que mi navegador o casi cualquier otro programa cargara la imagen grande. Al final, gimp lo hizo, pero es posible que desee volver a considerar el tamaño o las opciones de formato de archivo.
Pedro
Lo siento por eso. Creo que la imagen es válida, ya que Firefox me da los mismos errores al ejecutarla a través de convertir (ImageMagick). Posiblemente excede un umbral de tamaño arbitrario.
Geoffrey Irving

Respuestas:

4

Paso mucho tiempo escribiendo y depurando código paralelo, tanto con memoria compartida como distribuida, pero sin conocer su problema específico, solo puedo decirle qué funciona mejor para mí.

Sabiendo que las rutinas toman la cantidad de tiempo es una cosa importante si usted está buscando en la eficiencia computacional, pero si usted está preocupado acerca de la eficiencia en paralelo, entonces deberían estar más preocupados por lo que el código está haciendo cuando se está sin hacer ningún cálculo. Es como preocuparse por lo que hacen los niños cuando está demasiado tranquilo ...

Dado que está utilizando un enfoque de memoria compartida / distribuida híbrida, supongo que su código, en los espacios en blanco, está esperando una llamada MPI o en una variable mutex / condición. También puede envolver estas llamadas en temporizadores, y eso le dará una mejor idea de lo que lo está frenando, por ejemplo, si siempre es el mismo condicional o siempre el mismo en el MPI_REDUCEque se atascan sus hilos.

Una pieza de software que uso con bastante frecuencia es el Intel Vtune Amplifier XE . Tiene una buena característica / opción de trazado que visualiza la concurrencia de hilos. El programa trazará una trama muy similar a la suya, pero cuando un hilo espera en un mutex o variable de condición, dibuja una línea diagonal desde el hilo en espera, en el momento en que comenzó a esperar, hasta el hilo que realmente liberó el mutex o señaló la condición que estaba esperando, en el momento en que fue liberado / señalizado. Esto puede ser bastante complicado, pero hace que los cuellos de botella aparezcan de inmediato.

Finalmente, también recopilo estadísticas masivas, por ejemplo, para cada llamada mutex / señal / MPI, ¿cuáles fueron los tiempos de espera promedio y máximo? ¿Cuál es el histograma de los tiempos de espera recopilados? Si bien la trama le brinda una buena visión general, puede ser bastante desordenada cuando se trata de detalles finos.

Finalmente, una pregunta que no debe ser subestimada: ¿Cómo está recopilando sus tiempos? ¿Su temporizador no es lo suficientemente intrusivo como para no influir en su código? Uso el recuento de instrucciones de la CPU siempre que sea posible, es decir, RDTSCen arquitecturas x86. Esto generalmente solo agrega una sola instrucción a su código.

Pedro
fuente
Los datos ya tienen bloques alrededor de todas las esperas; en el diagrama se muestran en blanco para los hilos de trabajo inactivos y en amarillo para los hilos de comunicación en espera. Desafortunadamente, todas las esperas en el hilo de comunicación ocurren en una sola mantilla MPI_Waitsome debido a la asincronía. Vtune no se aplica en este caso ya que el rendimiento puramente roscado es esencialmente perfecto, pero gracias por el puntero. La sugerencia de histograma también es buena.
Geoffrey Irving
En cuanto a la sobrecarga de tiempo: estoy usando gettimeofday, que es necesario al menos alrededor de las secciones inactivas ya que allí uso variables de condición pthread. ¿Se puede hacer que el conteo de instrucciones de CPU funcione en tal situación? La sobrecarga ya es lo suficientemente baja, pero menor sería ciertamente mejor.
Geoffrey Irving
1
@GeoffreyIrving: Sí, puede usarlos, pero solo tienen sentido en las CPU que tienen el constant_tscindicador establecido (verificar /proc/cpuinfo) y si usa bloquear cada hilo en un núcleo específico, es decir, cada hilo siempre lee el mismo registro del mismo núcleo, por ejemplo, usando pthread_setaffinity_np. Tenga en cuenta que este último es específico de Linux y, por lo tanto, no es portátil.
Pedro
@GeoffreyIrving: incluso si está esperando un evento no revelado MPI_Waitsome, aún puede registrar qué solicitudes llegaron realmente y de dónde. Esta información puede o no ser útil ...
Pedro
5

A veces puede obtener una visión alternativa sobre los problemas de rendimiento a través de un análisis de recursos de alto nivel: ¿Existe un cuello de botella relevante como el ancho de banda de la memoria? ¿Cada hilo de trabajo hace la misma cantidad de trabajo? Estos datos pueden recopilarse fácilmente con likwid-perfctr del proyecto de código de Google LIKWID del conjunto de herramientas LIKWID . Si el perfil es tal que existen muchos puntos calientes diferentes, es posible que deba abordarlos uno por uno. También puede haber diferentes problemas, dependiendo de cuántos hilos / procesos se utilicen.

Georg Hager
fuente
En aras de una divulgación perfecta, Georg trabaja en el proyecto LIKWID y solicité esta respuesta porque quería complementar la gran respuesta de Pedro con otra perspectiva (y una gran herramienta disponible gratuitamente).
Aron Ahmadia
2

Cuando tengo un problema en una red de procesos altamente asincrónicos regidos por mensajes o eventos, utilizo un método que no es fácil pero es efectivo. Implicaba obtener registros de los procesos con marca de tiempo, fusionándolos en una línea de tiempo común y rastreando el progreso de algunos mensajes a medida que desencadenan actividades, desencadenando más mensajes. Lo que estoy buscando es un retraso entre el momento en que se recibe un mensaje y el momento en que se actúa, y entender el motivo del retraso. Cuando se encuentra un problema, se soluciona y el proceso se repite. De esta manera, puede obtener un rendimiento realmente satisfactorio.

Es importante ver cómo esto difiere de los enfoques en los que mide, mide, mide. Lo único que la medición puede decirle es dónde no mirar. El ajuste de rendimiento real requiere mirar cuidadosamente los detalles, desde una perspectiva de tiempo. Lo que está buscando no es dónde se gasta el tiempo, sino donde se gasta innecesariamente.

Buena suerte.

Mike Dunlavey
fuente
En otras palabras, no hay una visualización útil de los datos que tengo. :) Jed Brown sugirió Jumpshot (y las utilidades asociadas) como una forma de recopilar y visualizar los datos que sugieres, así que lo investigaré.
Geoffrey Irving
@Geof: Buena suerte con la visualización. La única herramienta que habría encontrado útil es algo para recopilar y fusionar los registros de eventos para poder seguir la ruta de una o más solicitudes a medida que avanza a través de los diversos hilos, porque esa es la única forma que conozco para detectar innecesarios retrasos En eso consiste cualquier problema de rendimiento: retrasos innecesarios.
Mike Dunlavey