Projektbeschreibung

Das Projekt strebt gleichermaßen Innovation als auch wiederverwertbare Ergebnisse an: durch die erweiterte Übersetzertechnologie wird die Entwicklung effizienter paralleler Programme nachhaltig vereinfacht und deren Verwertbarkeit über Plattformgrenzen ermöglicht. Zugleich stellen die Projektergebnisse eine innovative Grundlage für zukünftige, plattformunabhängige Programmierung, die gezielt Hardware-Details unter Berücksichtigung Algorithmen-spezifischer Optimierungsmöglichkeiten ausnutzen. Dabei wird besonderes Augenmerk darauf gelegt, dass sich die Technologie in Zukunft sowohl hardware- als auch algorithmenseitig erweitern lassen.

StrukturQuelle: Ecouss

Wie bereits eingangs erwähnt, lässt sich vollkommene Plattformunabhängigkeit des Quellcodes nicht erzielen, wenn Effizienzoptimierung ein relevantes Kriterium für die Codeausführung darstellt, was insbesondere bei Simulationen im ingenieurswissenschaftlichen Bereich zutrifft. Das Projekt zielt daher nicht so sehr auf komplette Plattformunabhängigkeit ab, als vielmehr darauf, den Optimierungs- und Anpassungs- (Portierungs-)prozess zu unterstützen und essentiell zu vereinfachen.

In einem ersten Schritt werden typische, derzeit manuell durchgeführte Optimierungsmuster in repräsentativen Programmen identifiziert. Diese werden durch Expertenwissen möglich, welches so derzeit nicht in der Quellsprache ausdrückbar ist. Daher erweitern wir die Quellsprache um neue Elemente („Semantische Annotationen“) um dieses Wissen ausdrücken zu können (z.B. ein Iterationskonstrukt, dessen Semantik keine schleifengetragenen Abhängigkeiten zulässt oder ein Konstrukt, in dem sich dynamische Programmierung direkt ausdrücken lässt. Hierdurch wird die immanente Parallelität direkt nutzbar; der Programmierer muss sich also nicht auf die Analyse-Fähigkeiten des Übersetzers verlassen. Diese neuartigen Sprachelemente werden in einem, der eigentlichen Übersetzung vorgeschalteten, Prozess von einem anpassbaren Übersetzer verarbeitet. Das Programm wird dann in Elemente der Originalsprache übersetzt. Der erzeugte Code ist derart, dass er zur Laufzeit des Programms durch einen dynamischen Übersetzer an die Zielhardware angepasst werden kann. Der Code bleibt somit portabel. Wesentliche Vorteile dieses Ansatzes gegenüber existierenden sind erstens, dass der Abbildungsprozess anpassbar ist (der Programmierer ist unabhängig vom Hersteller des Übersetzers), und zweitens, dass die Annotationen von Typsystemen/ Programmanalysen unterstützt werden, die eine semantikerhaltende Abbildung gewährleisten.

Dies führt nahtlos zum zweiten Pfeiler des Projekts: Wir geben dem Programmierer die Möglichkeit, für bestimmte Codeteile Optimierungsziele zu spezifizieren, bzw. Optimierungsverhalten zu parametrisieren. Dies beinhaltet Aspekte auf unterschiedlichen Transformations- und Abstraktionsebenen. Ein Beispiel ist die Organisation von Datenstrukturen. Diese hat Auswirkung auf die Ausführung von Schleifen (wodurch Schleifenausrollen und Verteilung auf den Cache in Abhängigkeit der Hardware-Charakteristika effizient gestaltet werden können). Ein weiteres Beispiel sind Beschränkungen an Parameter, die wiederum Auswirkung auf die Datenorganisation haben; bis hin zu „prinzipiellen“ Präferenzen welche Daten bevorzugt im Cache behalten werden oder wann Synchronisation spätestens stattfinden sollte. All solche Hinweise erlauben dem Übersetzer, hardware-abhängige Entscheidungen über den Optimierungsprozess zu fällen, die die spezifischen Charakteristika ausnutzen.

Zu diesem Zweck werden die oben genannten Annotationen/Spracherweiterungen sowie die Konstrukte der Quellsprache durch Programmanalysen/Typsysteme erweitert, die sicherstellen, dass der Code tatsächlich in einer Form ist, die es erlaubt das gewünschte Optimierungsziel zu erreichen. Dabei soll der Übersetzer prinzipiell dem Programmierer erläutern, welche Optimierungen (nicht) vorgenommen wurden und wieso. Entsprechend kann der Entwickler Schritte einleiten, um die Effizienz zu erhöhen.

Der dritte und letzte Pfeiler des Projekts bezieht sich auf die Übersetzung der Annotationen. Der oben erwähnte, vorgeschaltete Übersetzer ist nur für die Reduktion der Annotationen auf existierende Sprachelemente zuständig. Die eigentliche Abbildung und Anpassung auf die Zielarchitektur geschieht entweder zur Laufzeit durch einen dynamischen (just-in-time) Übersetzer oder durch einen entsprechend verzweigten Code, der zur Laufzeit hardwarespezifische Entscheidungen fällt. In allen Fällen soll LLVM als prinzipielle Backend-Lösung verwendet und entsprechend erweitert werden, da dieser Übersetzer sowohl breiten Einsatz findet, als auch sich durch seine hohe Adaptabilität auszeichnet.

Annotationen sind aufgrund der vorgeschalteten Übersetzung leicht zu identifizieren und aufgrund der Programmdarstellung von LLVM leicht zu berücksichtigen. Vorteil dieses Vorgehens ist, dass das Programm plattform-unabhängig verteilt werden kann (LLVM bitcode). Die Abbildung selbst wird vom Experten in Form einer Bibliothek zur Verfügung gestellt. Diese wird dann zum Programmstart auf das Programm angewandt. Zum Beispiel: Der Experte stellt eine für die Zielarchitektur optimierte Implementierung der „Dynamischen Programmierung“ bereit. Diese wird dann vom JIT-Übersetzer beim Programmstart mit dem Programm verschmolzen. Beide werden dann mit klassischen Optimierungs- und Codegenerierungstechniken auf die Zielmaschine übersetzt.

Im Rahmen des oben angeführten Beispiels ergeben sich für den Experten zwei Möglichkeiten für eine spezifische Maschine ein hochoptimiertes und parallelisiertes Rahmenwerk zum Programmieren bereitzustellen: existieren bereits Annotationsvorlagen die für die spezifischen Anwendungstypen geeignet sind, so können diese mit hardware-spezifischen Transformationsmustern erweitert werden, um gezielte Anforderungen zu erfüllen. In vielen Fällen wird jedoch auch die Spezifizierung von Hardware-Charakteristika (wie z.B. die Wortlänge in Vektorregistern moderner x86 Prozessoren) ausreichen. Sollten keine geeigneten Erweiterungen vorliegen, so kann er welche erstellen, die dann dem Programmierer ermöglichen, die Anteile seines Programms, die dynamische Programmierung einsetzen, zu kennzeichnen.

Die Kommentarfunktion ist geschlossen.