Extraktion und Generierung von Ressourcenzwillingen

Abstract - In den bisherigen Blogposts sind wir auf die Idee und die Zielsetzung des Projekts TwinSpace eingegangen und haben verschiedene Bausteine zur technischen Umsetzung präsentiert, nämlich die LPDL als Lastbeschreibungssprache sowie die dazugehörigen Extraktoren und Generatoren. Mit Hilfe der LPDL können Modelle des extra-funktionalen Verhalten von Software-Komponenten und -systemen (beispielsweise Laufzeit, Anzahl und Art der Operationen, Speicherverbrauch, Kommunikationsverhalten, …) spezifiziert werden ohne konkrete Algorithmen offenlegen zu müssen. Die Modelle können entweder mittels der Extraktoren automatisch aus vorhandenen Software-Komponenten erzeugt werden oder aber von Hand geschrieben werden. Die Modelle dienen danach als Eingabe für die Generatoren, die anhand der Spezifikation in den LPDL-Modellen passende Ressourcenzwillinge erzeugen. Diese können dann zum Beispiel genutzt werden, um verschiedene Hardwareplattformen oder Compiler zu bewerten. Heute wollen wir die Umwandlung von Softwarekomponenten in Ressourcenzwillinge anhand eines Beispiels etwas genauer beleuchten. In späteren Blogposts werden auch die Systemebene, Metriken zur Bewertung der Zwillinge und die Einbindung in den automobilen Entwicklungsprozess ein Thema sein.

Ein einfaches Beispiel

Zunächst wollen wir ein einfaches synthetisches Beispiel für eine Softwarekomponente vorstellen, wie sie ähnlich in eingebetteten Systemen öfters vorkommen. Diese Komponente ist in Abbildung 1 skizziert. Abhängig vom aktuellen Systemzustand werden verschiedene Gleitkommaberechnungen durchgeführt. Im Projekt TwinSpace betrachten wir sowohl Softwarekomponenten, die als C-Quellcode vorliegen, als auch Komponenten, die nur als Objektcode verfügbar sind. Unsere Beispielkomponente haben wir beispielsweise für Infineon AURIX übersetzt, um einen Binärcode-Extraktor anwenden zu können.

Abbildung 1: Eine einfache Softwarekomponente

Extraktion des Ressourcenzwillings mittels statischer Programmanalyse

Zur Extraktion des Ressourcenzwillings aus dem Binary wird zunächst der Kontrollflussgraph rekonstruiert. Dies funktioniert in den meisten Fällen vollautomatisch. Falls aber beispielsweise Funktionszeiger nicht aufgelöst werden können, besteht die Möglichkeit, die Ziele mittels Annotationen zu spezifizieren. Der Kontrollflussgraph unserer Beispielkomponente ist links in Abbildung 4 dargestellt. Gut sichtbar ist die Verzweigung, die aus dem „if“ im Quellcode resultiert. Die Schleife im Quellcode wurde vom Compiler ausgerollt.

Nach der Kontrollflussrekonstruktion werden in jedem Basisblock des Kontrollflussgraphen die vorhandenen Instruktionen klassifiziert. Für die LPDL sind insbesondere die mathematischen und logischen Operationen von Bedeutung. Außerdem werden gelesene und geschriebene Variablen gesammelt. Sowohl die grobe Struktur der Softwarekomponente als auch die Anzahl und Art der genutzten Operationen werden im XML-basierten LPDL-Modell der Beispielkomponente gespeichert. Ein Ausschnitt des extrahierten LPDL-Modells ist in Abbildung 2 dargestellt. Dieses Modell wird im nächsten Schritt zur Generierung des Ressourcenzwillings genutzt.

Abbildung 2: Ausschnitt aus dem LPDL-Modell der Beispielkomponente

Generierung des Ressourcenzwillings

Das LPDL-Modell enthält alle wichtigen Informationen zur Beschreibung der extra-funktionalen Eigenschaften unserer Beispielkomponente. Neben der groben Struktur sind dies insbesondere die Anzahl und Art der genutzten mathematischen und logischen Operationen. In unserem Beispiel sind dies hauptsächlich Gleitkommaoperationen. Diese Information wird von den Zwillingsgeneratoren genutzt, um die Ressourcenzwillinge, die das nicht-funktionale Verhalten der Softwarekomponente simulieren, zu erzeugen. Dazu wird entsprechend der Angaben im LPDL-Modell C-Code mit den nötigen Operationen generiert. Ein Ausschnitt des generierten Codes ist in Abbildung 3 zu sehen. Der Ausschnitt zeigt den Zwillingscode, der für den Teil innerhalb des „if“ der originalen Softwarekomponente generiert wurde. Es wird die gleiche Anzahl an Fließkommaoperationen verwendet (z.B. 2 Divisionen und 3 Multiplikationen), aber von den konkret genutzten Variablen und Berechnungsschritten abstrahiert. Die verwendeten Konstanten im Original fallen im Zwilling zum Beispiel weg.

Abbildung 3: Ausschnitt aus dem generierten C-Code des Zwillings

Vom Original zum Zwilling

In einem letzten Schritt übersetzen wir den Ressourcenzwilling ebenso wie die originale Softwarekomponente für Infineon AURIX um die Kontrollflussgraphen von Original und Zwilling vergleichen zu können (Abbildung 4). Es zeigt sich, dass beide wie gewünscht eine ähnliche Struktur aufweisen. Da im Zwilling die Konstanten des Originals nicht genutzt werden, fällt der dazu genutzte Code im Zwilling weg. Dies kann man auch im Kontrollflussgraph sehen: Der Block auf dem rechten Pfad ist im Zwilling deutlich verkleinert im Vergleich zum Original.

Um die Ressourcenzwillinge mit den Originalkomponenten vergleichen zu können, gibt es im Projekt TwinSpace eine extra Arbeitsgruppe, die sich mit relevanten Metriken beschäftigt. Diese Metriken werden auch genutzt, um die Extraktoren und Generatoren weiter zu verbessern, damit möglichst präzise Ressourcenzwillinge erzeugt werden können. Details zu den in TwinSpace verwendeten Metriken wollen wir in einem späteren Blogpost beleuchten.

Abbildung 4: Kontrollflussgraphen von Original (links) und Zwilling (rechts)