Hand in Hand für das Multicore-Debugging und -Tracing

Seite: 2/2

Anbieter zum Thema

Debug-Konzepte für SMP-und AMP- Systeme

Das gesamte SMP-System wird über eine einzige Instanz des Debuggers kontrolliert. Über diese Instanz werden alle Cores synchron gestartet und gestoppt. In einer GUI werden sowohl die gemeinsam genutzten Daten und Peripheriemodule als auch die core-spezifischen Eigenschaften des Systems wie Core Register, Stack Frame oder Caches dargestellt (siehe Bild am Anfang des Artikels)

Beim Debugging von AMP-Systemen wird für jeden Core eine eigene Debugger-Instanz gestartet.
Beim Debugging von AMP-Systemen wird für jeden Core eine eigene Debugger-Instanz gestartet.
(Grafik: Lauterbach)

Da erst zur Programmlaufzeit feststeht, welcher Core welche Aufgabe – im Folgenden sprechen wir von Tasks - bearbeitet, müssen die Breakpoints vom Debugger so gesetzt werden, dass sie für jeden Core gelten. Beim Stopp an einem Breakpoint blendet der Debugger den Zustand des Gesamtsystems immer aus der Perspektive des Cores ein, auf dem der Breakpoint zugeschlagen hat. Damit dies möglich ist, muss die Debug-Logik des Prozessors bei jedem Stopp eindeutig anzeigen, auf welchem Core welcher Breakpoint zum Stopp geführt hat.

Für das Debugging eines Tasks genügt es in der Regel, den Zustand des Gesamtsystems aus der Perspektive des Cores zu untersuchen, der diesen Task gerade bearbeitet. Dennoch muss der Debugger selbstverständlich die Möglichkeit bieten, jederzeit den Zustand anderer Tasks bzw. Cores zu inspizieren.

Beim Debugging von AMP-Systemen wird für jeden Core eine eigene Instanz des Debuggers gestartet, da jeder Core die ihm zugeteilte Aufgabe mit einem separaten Programm bearbeitet. Jede Debugger-Instanz visualisiert und modifiziert die Systeminformationen ihres Cores und setzt auch die Breakpoints so, dass sie nur für diesen Core gelten. Ob es ausreicht, dass jede Instanz nur ihren Core startet und stoppt, oder ob alle Cores synchron gestartet und gestoppt werden, sollte für den Anwender je nach Testszenario konfigurierbar sein.

Die Informationen zur Programmausführung, die von den einzelnen Core-Trace-Modulen erzeugt werden, müssen zur Programmlaufzeit an den Debugger übertragen werden. Dazu muss der Multicore-Prozessor über einen Off-Chip-Traceport mit angemessener Bandbreite verfügen. Die von parallelen Traceports erreichten Übertragungsraten reichen für moderne Prozessoren oft nicht mehr aus. Deshalb sind die meisten Multicore-Prozessoren heute mit seriellen Traceports ausgestattet.

Die Anzahl der Cores, deren Trace-Daten verlustfrei übertragen werden können, wird sowohl durch die Bandbreite des Traceports als auch durch die Menge an Trace-Daten bestimmt, die ein Core bei einer bestimmten Frequenz erzeugt. Erzeugt ein Core bei einer Frequenz von 1 GHz beispielsweise bis zu 2 GBit Trace-Daten pro Sekunde, kann ein Traceport mit einer Bandbreite von 12 GBit/s die Trace-Daten von maximal 6 Cores übertragen.

Diese Limitierung kann unter bestimmten Umständen umgangen werden:

  • Einzelne Cores sind weitgehend inaktiv (idle) und erzeugen kaum Trace-Daten.
  • Dem Traceport sind auf dem Prozessor große FIFOs vorgelagert, die Lastspitzen abpuffern können.
  • Die Core-Trace-Logik lässt sich so programmieren, dass nur für einen speziellen Programmabschnitt bzw. einen einzelnen Task Trace-Daten erzeugt werden.

Auf Debuggerseite werden alle Tracedaten gemeinsam in einem Trace-Speicher abgelegt. Dieser kann eigentlich nicht groß genug sein. Üblich sind heute meist 4 GByte. Auch bei der Analyse und Darstellung von Core-Trace-Daten unterscheidet der Debugger zwischen SMP- und AMP-Systemen.

Die Debug-Instanz, die für ein SMP-System gestartet wurde, hat Zugriff auf die Trace-Daten aller Cores. Somit ist es grundsätzlich möglich, das Laufzeitverhalten eines einzelnen Cores, aller Cores sowie des Gesamtsystems zu untersuchen.

Trace-Konzepte für SMP-und AMP-Systeme

Die Funktionslaufzeiten innerhalb des Tasks TASKRC1 werden analysiert. Auf welchem Core die einzelne Funktion gelaufen ist, spielt für die Auswertung keine Rolle.
Die Funktionslaufzeiten innerhalb des Tasks TASKRC1 werden analysiert. Auf welchem Core die einzelne Funktion gelaufen ist, spielt für die Auswertung keine Rolle.
(Bild: Lauterbach)

Für die Fehlersuche in einem Task bzw. für task-spezifische Laufzeitmessungen lässt sich die Trace-Information gezielt für einen einzelnen Task analysieren und darstellen. Stehen Fragestellungen wie „Von welchen Cores wurde mein Task bearbeitet?“ oder „Wie sieht die Laufzeit-Auslastung meiner Cores aus?“ im Vordergrund, dann ist es zweckdienlich, die Trace-Information für alle Cores gemeinsam darzustellen.

Für ein SMP-System wird angezeigt, wann welcher Task von welchem Core bearbeitet wurde.
Für ein SMP-System wird angezeigt, wann welcher Task von welchem Core bearbeitet wurde.
(Bild: Lauterbach)

Auch in einem AMP-System überträgt der Prozessor die Trace-Daten aller Cores über einen gemeinsamen Traceport. Die Trace-Hardware des Debuggers sorgt dafür, dass diese in der Empfangsreihenfolge im Trace-Speicher abgelegt werden. Dadurch bleibt der zeitliche Bezug der einzelnen Programmabläufe erhalten.

Um Laufzeitmessungen vornehmen zu können und um die Programmabläufe auf den einzelnen Cores zeitlich zueinander in Beziehung setzen zu können, erhalten die Trace-Daten beim Speichern in den Trace-Speicher einen Zeitstempel. Da durch das Aufsammeln der Trace-Daten im Prozessor und durch die Übertragungstechnik variable Verzögerungen entstehen können, stimmt dieser Zeitstempel nicht exakt mit dem ursprünglichen Programmablauf überein. Um exakte Zeitmessungen zu ermöglichen, bieten einige Multicore-Prozessoren heute schon die Möglichkeit einen prozessor-globalen Zeitstempel in die einzelnen Core-Traces zu integrieren.

Die zeitliche Synchronisation von Trace-Informationen erlaubt die Überprüfung, welche Programmausschnitte die parallel arbeitenden Cores zu einem bestimmten Zeitpunkt bearbeitet haben.
Die zeitliche Synchronisation von Trace-Informationen erlaubt die Überprüfung, welche Programmausschnitte die parallel arbeitenden Cores zu einem bestimmten Zeitpunkt bearbeitet haben.
(Grafik: Lauterbach)

Für die Auswertung der Trace-Daten bezieht jede Debug-Instanz aus dem Trace-Speicher die Informationen, die für den von ihr kontrollierten Core relevant sind. Um das Zusammenspiel der einzelnen Cores zu testen und möglichst schnell komplexe Systemfehler zu lokalisieren, bietet der Debugger die Möglichkeit die einzelnen Aufzeichnungen zeitlich korreliert darzustellen.

Neben den Core-Aktivtäten gibt es in einem Multicore-Prozessor weitere prozessor-interne Abläufe, die für das Multicore-Debugging von Interesse sein können. Informationen darüber sammelt ein so genannter System-Trace im Prozessor für die Ausgabe auf.

Diagnosedaten über die Zustandsänderungen von Mutexes werden durch Codeinstrumentierung erzeugt.
Diagnosedaten über die Zustandsänderungen von Mutexes werden durch Codeinstrumentierung erzeugt.
(Bild: Lauterbach)

Der System-Trace unterstützt hauptsächlich zwei Arten von Informationen:

  • Diagnosedaten im Printf-Stil, die durch Codeinstrumentierung erzeugt werden (siehe Bild links).
  • Diagnosedaten, die von der prozessor-internen Hardware-Überwachung erzeugt werden. Überwacht werden können beispielsweise Zugriffe auf einzelne RAM-Adressen oder die Aktivitäten in einer Clock Domain.

Ein Clock Management Monitor generiert Informationen zur Aktivität in einer Clock-Domain.
Ein Clock Management Monitor generiert Informationen zur Aktivität in einer Clock-Domain.
(Bild: Lauterbach)

* Andrea Martin ist Diplom-Informatikerin. Seit 1994 ist sie bei Lauterbach für das Training verantwortlich.

Jetzt Newsletter abonnieren

Verpassen Sie nicht unsere besten Inhalte

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

(ID:42675722)