Möglichkeiten zur Visualisierung von Ereignisdaten auf der Suche nach Leistungsproblemen


10

Ich versuche, eine MPI-Anwendung mit einem stark asynchronen Kommunikationsmuster zu optimieren. Jeder Rang hat eine Liste der zu berechnenden Dinge und sendet nach Bedarf Nachrichten, wenn sich die Ein- oder Ausgänge auf einem anderen Rang befinden. Zusätzlich wird jeder Rang mit einem Thread versehen (derzeit mit einem Kommunikationsthread und 5 Arbeitern).

Ich habe den Code mit Timern um die verschiedenen leistungskritischen Teile des Codes herum instrumentiert, wodurch ich eine Liste von (Start-, End-, Typ-) Tripeln für jeden Thread bekomme. Auf offensichtliche Weise dargestellt, mit Zeit als horizontale Achse, Rang und Faden als vertikale Achse und Farbe, die angibt, was jeder Faden gerade tut, erhalte ich ein Bild wie dieses für 16 Ränge mit 6 Fäden / Rang:

Pentago Rang und Thread Geschichte

Meine Frage lautet: Welche anderen Möglichkeiten zur Visualisierung dieser Daten können dazu beitragen, Leistungsprobleme zu beheben? Hat jemand einen bevorzugten Plottyp, den er bei der Profilerstellung für asynchrone Anwendungen verwendet?

Dieser Datensatz ist insofern begrenzt, als er die Datenflussstruktur nicht kennt, aber ich möchte so viel Einblick wie möglich daraus gewinnen, bevor ich versuche, etwas Komplizierteres zu sammeln.

Das unkomprimierte Bild ist hier, falls sich jemand umschauen möchte (es konnte nicht über die normale Route hochgeladen werden). Leider akzeptiert Firefox es nicht, obwohl ich glaube, dass es gültig ist, möglicherweise weil es einfach zu groß ist.


Ich hatte einige Probleme damit, meinen Browser oder fast jedes andere Programm dazu zu bringen, das große Bild zu laden. Am Ende hat es gimp getan, aber vielleicht möchten Sie die Größen- oder Dateiformatoptionen überdenken.
Pedro

Das tut mir leid. Ich denke, das Bild ist gültig, da Firefox mir die gleichen Fehler gibt, die es durch Konvertieren (ImageMagick) ausführen. Möglicherweise überschreitet es einen beliebigen Größenschwellenwert.
Geoffrey Irving

Antworten:


4

Ich verbringe viel Zeit damit, parallelen Code zu schreiben und zu debuggen, sowohl mit gemeinsamem als auch mit verteiltem Speicher, aber ohne Ihr spezifisches Problem zu kennen, kann ich Ihnen nur sagen, was für mich am besten funktioniert.

Zu wissen , welche Routinen nehmen , wie viel Zeit ist eine wichtige Sache , wenn man sich die Recheneffizienz suchen, aber wenn Sie parallel Effizienz besorgt sind, sollten Sie dann mehr über besorgt sein , was Ihr Code tut , wenn es nicht jede Berechnung zu tun. Ein bisschen wie sich Sorgen zu machen, was die Kinder tun, wenn es zu leise ist ...

Da Sie einen hybriden Ansatz für gemeinsam genutzten / verteilten Speicher verwenden, wartet Ihr Code in den Leerzeichen entweder auf einen MPI-Aufruf oder auf eine Mutex- / Bedingungsvariable. Sie können diese Aufrufe auch in Timer einbinden, und das gibt Ihnen ein besseres Bild davon, was Sie verlangsamt, z. B. wenn es immer die gleiche Bedingung oder immer die gleiche ist MPI_REDUCE, auf der Ihre Threads hängen bleiben.

Eine Software, die ich ziemlich oft benutze, ist der Intel Vtune Amplifier XE . Es hat eine nette Plot-Funktion / Option, die die Parallelität von Threads visualisiert. Das Programm zeichnet einen Plot, der Ihrem sehr ähnlich ist. Wenn ein Thread jedoch auf einen Mutex oder eine Bedingungsvariable wartet, zeichnet er eine diagonale Linie vom wartenden Thread zu dem Zeitpunkt, zu dem er zu warten begann, zu dem Thread, der den Mutex tatsächlich freigegeben oder signalisiert hat der Zustand, auf den es gewartet hat, als es freigegeben / signalisiert wurde. Dies kann ziemlich chaotisch sein, führt jedoch sofort zu Engpässen.

Schließlich sammle ich auch Massenstatistiken, z. B. für jeden Mutex / Signal / MPI-Anruf. Wie hoch waren die durchschnittlichen und maximalen Wartezeiten? Was ist das Histogramm der gesammelten Wartezeiten? Während die Handlung Ihnen einen schönen Überblick gibt, kann es ziemlich chaotisch werden, wenn es um die feinen Details geht.

Zum Schluss eine nicht zu unterschätzende Frage: Wie sammeln Sie Ihre Timings? Ist Ihr Timer nicht aufdringlich genug, um Ihren Code nicht zu beeinflussen? Ich verwende die Anzahl der CPU-Befehle, wann immer dies möglich ist, dh RDTSCauf x86-Architekturen. Dies fügt Ihrem Code normalerweise nur eine einzige Anweisung hinzu.


Die Daten haben bereits Blöcke um alle Wartezeiten; Im Diagramm werden sie für Leerlauf-Worker-Threads als weiß und für wartende Kommunikationsthreads als gelb angezeigt. Leider treten aufgrund der Asynchronität alle Wartezeiten im Kommunikationsthread in einem einzigen Blanket MPI_Waitsome auf. Vtune gilt in diesem Fall nicht, da die reine Thread-Leistung im Wesentlichen perfekt ist, aber danke für den Zeiger. Der Histogrammvorschlag ist auch gut.
Geoffrey Irving

Was den Timing-Overhead betrifft: Ich verwende gettimeofday, was zumindest in den Leerlaufabschnitten erforderlich ist, da ich dort pthread-Bedingungsvariablen verwende. Kann die Anzahl der CPU-Befehle in einer solchen Situation zum Funktionieren gebracht werden? Der Overhead ist bereits niedrig genug, aber niedriger wäre sicherlich schöner.
Geoffrey Irving

1
@GeoffreyIrving: Ja, Sie können sie verwenden, aber sie sind nur auf CPUs sinnvoll, auf denen das constant_tscFlag gesetzt ist (überprüfen /proc/cpuinfo). Wenn Sie die Sperrung jedes Threads für einen bestimmten Kern verwenden, dh jeder Thread liest immer dasselbe Register von demselben Kern. zB mit pthread_setaffinity_np. Beachten Sie, dass letzteres Linux-spezifisch und daher nicht portabel ist.
Pedro

@GeoffreyIrving: Auch wenn Sie mit auf ein nicht bekannt gegebenes Ereignis warten MPI_Waitsome, können Sie dennoch aufzeichnen, welche Anfragen tatsächlich eingegangen sind und von wo. Diese Informationen können von Nutzen sein oder auch nicht ...
Pedro

5

Manchmal können Sie über eine Ressourcenanalyse auf hoher Ebene eine alternative Sicht auf Leistungsprobleme erhalten: Gibt es einen relevanten Engpass wie die Speicherbandbreite? Erledigt jeder Worker-Thread die gleiche Menge an Arbeit? Diese Daten können problemlos mit likwid-perfctr aus dem LIKWID-Tool-Suite- LIKWID-Google -Codeprojekt erfasst werden . Wenn das Profil so ist, dass viele verschiedene Hot Spots vorhanden sind, müssen Sie diese möglicherweise einzeln angehen. Abhängig von der Anzahl der verwendeten Threads / Prozesse können auch unterschiedliche Probleme auftreten.


Im Interesse einer perfekten Offenlegung arbeitet Georg am LIKWID-Projekt und ich habe um diese Antwort gebeten, weil ich Pedros großartige Antwort durch eine andere Perspektive (und ein großartiges, frei verfügbares Tool) ergänzen wollte.
Aron Ahmadia

2

Wenn ich ein Problem in einem Netzwerk hoch asynchroner Prozesse habe, die von Nachrichten oder Ereignissen gesteuert werden, verwende ich eine Methode, die nicht einfach, aber effektiv ist. Es umfasste das Abrufen von Protokollen mit Zeitstempel der Prozesse, das Zusammenführen dieser Protokolle zu einer gemeinsamen Zeitachse und das Verfolgen des Fortschritts einiger Nachrichten beim Auslösen von Aktivitäten sowie das Auslösen weiterer Nachrichten. Was ich suche, ist die Verzögerung zwischen dem Zeitpunkt des Empfangs einer Nachricht und dem Zeitpunkt, an dem sie bearbeitet wird, und das Verständnis des Grundes für die Verzögerung. Wenn ein Problem gefunden wird, wird es behoben und der Vorgang wiederholt. Auf diese Weise können Sie eine wirklich zufriedenstellende Leistung erzielen.

Es ist wichtig zu sehen, wie sich dies von Ansätzen unterscheidet, bei denen Sie messen, messen, messen. Das einzige, was die Messung Ihnen möglicherweise sagen kann, ist, wo Sie nicht suchen müssen. Für eine echte Leistungsoptimierung müssen die Details aus zeitlicher Sicht sorgfältig betrachtet werden. Was Sie suchen, ist nicht, wo Zeit verbracht wird, sondern wo sie unnötig verbracht wird.

Viel Glück.


Mit anderen Worten, es gibt keine nützliche Visualisierung der Daten, die ich habe. :) Jed Brown schlug Jumpshot (und die zugehörigen Dienstprogramme) als eine Möglichkeit vor, die von Ihnen vorgeschlagenen Daten zu sammeln und zu visualisieren, also werde ich das untersuchen.
Geoffrey Irving

@Geof: Viel Glück bei der Visualisierung. Das einzige Tool, das ich als nützlich empfunden hätte, ist das Sammeln und Zusammenführen der Ereignisprotokolle, damit ich dem Pfad einer oder mehrerer Anforderungen auf ihrem Weg durch die verschiedenen Threads folgen kann, da dies der einzige mir bekannte Weg ist, um unnötige Fehler zu erkennen Verzögerungen. Daraus besteht jedes Leistungsproblem - unnötige Verzögerungen.
Mike Dunlavey
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.