Wer Software für einen Rechner übersetzt, der 135 Millionen Euro gekostet hat, der wählt Sprachen und Compiler besonders sorgfältig aus. Zwei Mitarbeiter des Leibniz-Rechenzentrums der Bayerischen Akademie der Wissenschaften berichten über für gut befundene Tools ihres Boliden Super MUC.
Der bei Weitem überwiegende Teil der CPU-Zyklen, die die HPC-Systeme am LRZ [1] im Zuge ihrer Berechnungen ausführen, entfällt auf Binärcode. Die zugrunde liegenden Quelltexte wurden in einer der drei klassischen HPC-Sprachen verfasst und dann kompiliert: Fortran [2], C++ [3] oder C [4].
Warum gerade diese Sprachen? Weil sie bereits seit langer Zeit sehr effizienten Code generieren. Für die am nationalen Höchstleistungssystem Super MUC ([5], siehe Kasten “Der Super MUC”) im ersten Halbjahr 2017 aktiven Projekte zeigt die Abbildung 1 eine Statistik der genutzten Sprachen.
Der Super MUC
Der Super MUC ist ein Hochleistungsrechner des Leibniz-Rechenzentrums der Bayerischen Akademie der Wissenschaften in Garching bei München. Der von IBM gebaute und inklusive Gebäude rund 135 Millionen Euro teure Rechner bringt es mit 19 Compute-Inseln mit je etwa 8200 Rechenkernen und sechs Inseln neuerer Bauart mit je 14300 Rechenkernen heute auf rund 6 Petaflops. Insgesamt stehen fast 500 TByte Hauptspeicher und fast 20 PByte externer Speicher für Daten bereit.
Neben hoher Rechenleistung kann der Super MUC auch mit einer hohen Energieeffizienz punkten: Seine Warmwasserkühlung braucht 25 Prozent weniger Strom als ein System mit Kälteaggregaten. Noch einmal 10 Prozent Energie spart die Wasserkühlung im Vergleich zu einer Luftkühlung mit Lüftern.
Bei seiner Einweihung im Jahr 2012 war der Super MUC mit damals rund 3 PFlops einmal der schnellste Rechner Europas und der viertschnellste in der Welt. Inzwischen landet er auf der weltweiten Top-500-Liste nur noch auf Platz 40 und wurde auch in Deutschland mehrfach überholt, zum Beispiel von einem Cray XC40 im Höchstleistungs-Rechenzentrum Stuttgart oder dem IBM Blue Gene/Q im Forschungszentrum Jülich.
Mit dem Super MUC rechnen Forscher aus Deutschland und 24 anderen europäischen Ländern sowie Israel und der Türkei. Geowissenschaftler, Physiker, Astronomen, Mathematiker und Mediziner profitieren ebenso wie Ingenieure und Klimaforscher.
Konkrete Projekte
Das Spektrum der konkreten Projekte, die den Garchinger Computer nutzen, ist sehr breit. Ein Projekt widmet sich etwa der Untersuchung des turbulenten Strömungsverhaltens in Kraftwerken, das zu thermischen Ermüdungsbrüchen von Bauteilen führen kann. Durch eine Kombination aus Messungen in der Realität und numerischen Berechnungen mit Hilfe des Supercomputers wollen die Forscher solchen Schäden vorbeugen. Ein anderes Projekt hat sich zum Ziel gesetzt, mit der selbst entwickelten Erdbeben-Simulationssoftware Seis-Sol den komplizierten Wellen- und Bruchphänomenen bei solchen Ereignissen auf die Spur zu kommen. Damit ist es möglich, das Grundverständnis der Erdbebendynamik zu verbessern.
Ein anderes Projekt bemüht sich den Fluglärm in der Startphase zu vermindern, indem es spezielle Düsen durch großflächige Simulationen auf der Basis eines hochaufgelösten Netzes mit bis zu einer Milliarde Messzellen untersucht. Ein weiteres Beispiel ist ein Projekt, bei dem Wissenschaftler die Rechenleistung des Super MUC nutzen, um detaillierte und genaue Modelle von Protein-Protein-Wechselwirkungen zu simulieren und damit noch effektivere Medikamente gegen HIV möglich zu machen.
Auch Astronomen und Astrophysiker benutzen den Super MUC für vielfältige Simulationen, beispielsweise zur Entstehung von Sternen und Galaxien in verschiedenen Entwicklungsstadien oder zum Nachstellen des geheimnisvollen dunklen Universums.

Abbildung 1: Anteile der Programmiersprachen an aktiven Projekten, die im ersten Halbjahr 207 auf dem Super MUC liefen.
Die Säulenlängen in der Abbildung verhalten sich proportional zu der Anzahl der CPU-Zyklen, die den Projekten zugewiesen waren. Da zahlreiche Projekte Sprachmischungen benutzen (nur 32 Prozent aller Zyklen gehören zu Projekten, die nur eine Sprache verwenden), sind diese Mischungen als eigene Kategorien vertreten. An rund 72 Prozent aller zugewiesenen Projektressourcen ist Fortran beteiligt, an 54 Prozent C++ und an 41 Prozent C.
Die auf Super MUC eingesetzten Compiler für alle drei Sprachen sind die von Intel, die – gebündelt mit anderen HPC-Software-Komponenten – als “Parallel Studio Cluster Edition” erhältlich sind. In geringem Umfang sind auch andere Compiler, insbesondere die der GCC (GNU Compiler Collection [6]) vertreten. Die Kategorie “Unbekannt” steht für Projekte, die spezielle, meist kommerzielle Anwendungen nutzen, bei denen nicht bekannt ist, in welcher Sprache der Hersteller sie implementiert hat.
Alle diese klassischen HPC-Sprachen unterliegen einem Standardisierungs-Prozess, der in regelmäßigen Abständen für die Integration neuer Sprachmerkmale sorgt. Tabelle 1 gibt einen Überblick über die letzten drei Standardversionen aller HPC-Sprachen und gegebenenfalls unmittelbar bevorstehende neue Editionen.
| Bezeichnung | Erscheinungsjahr | Wichtigste Neuerungen |
|---|---|---|
| Fortran 95 | 1995 | Nur kleinere Korrekturen und Ergänzungen zu Fortran 90 |
| Fortran 2003 | 2004 | Objektorientierung, Interoperabilität mit C, parametrisierte Datentypen |
| Fortran 2008 | 2010 | Parallele Programmierung mit Coarrays, Submodule, DO CONCURRENT |
| Fortran 2015 | vorauss. 2018 | Erweiterung der C-Interoperabilität, Erweiterung des Coarray-Programmiermodells |
| C++03 | 2003 | Nur kleinere Korrekturen zu C++98 |
| C++11 | 2011 | Lambdas, Typ-Inferenz mit »auto«, Variadic Templates, Threading Memory Modell, Shared Pointers |
| C++14 | 2015 | Generische Lambdas, andere geringfügige Erweiterungen zu C++11 |
| C++17 | vorauss. 2017 | Structured Bindings, Nutzung von »auto« in Templates |
| C95 | 1995 | Minimale Modifikationen zu C90 |
| C99 | 1999 | Neue Datentypen, verbesserte Kompatibilität zu C++, restrict Keyword, mehr Kernfeatures für Felder und Indizierung |
| C11 | 2011 | Multithreading-Support, Alignment-Spezifikation |
Programmiermodelle und HPC-Software
Der größte Teil der Projektarbeit auf den Höchstleistungsrechnern des LRZ basiert auf Code, den Wissenschaftler über viele Jahre weiterentwickeln. Die passende Programmiersprache wählen die Programmautoren in der Regel am Anfang des Entwicklungsprozesses (in der Designphase). Die Entscheidung beruht oft auch auf ihren Vorkenntnissen oder Vorlieben. Die Wahl fällt im Regelfall eher konservativ aus – zum einen die Sprache betreffend, zum anderen auch bezüglich der Sprachmerkmale, auf die die Programmierer zurückgreifen.
Sprachmerkmale, die erst vor Kurzem definiert wurden, kommen im Produktionscode erst dann zum Einsatz, wenn gesichert ist, dass sie auch auf andere Plattformen portiert sind und dort fehlerfrei und möglichst performant funktionieren. Solche neuen Sprachmerkmale (ein typisches Beispiel ist die Objektorientierung) zielen zudem häufig eher auf eine effiziente Programmiermethodik als auf höchste Leistung. Deshalb gilt es, sie mit Bedacht (und in daten- oder rechenintensiven Kontexten möglichst gar nicht) zu benutzen.
Außerdem ist die verwendete Programmiersprache bei Weitem nicht der einzige Faktor, von dem der Projekterfolg abhängt. Ganz wesentlich ist auch die Unterstützung für parallele Programmiermodelle wie Open MP (Open Multi Processing, ein Direktiven-basiertes Modell für die Parallelisierung mit Threads in einem gemeinsamen Hauptspeicher, [7]) sowie MPI (Message Passing Interface, ein Bibliothek-basiertes System zur Parallelisierung auf verteiltem Hauptspeicher, [8], typischerweise über ein die Rechenknoten verbindendes Hochgeschwindigkeitsnetzwerk). Implementierungen dieser Modelle stehen für alle HPC-Sprachen zur Verfügung.
Zudem machen Standardschnittstellen sehr häufig benutzte Funktionen als Bibliotheken verfügbar, die für die Zielplattform optimiert sind. Hier wären etwa Blas/Lapack als Standard für Operationen aus der linearen Algebra zu nennen oder FFTW als Standard für Fourier-Transformationen aller Art. Nicht zu vergessen auch die Bibliotheken für Daten-I/O wie MPI-IO, HDF5 oder Net CDF. Entsprechend definierte Schnittstellen sind meist für alle HPC-Sprachen zu haben.
Eine gewisse Ausnahmestellung hat die Implementierung von skalierbaren C++-Containern in den Threading Building Blocks (TBB) erlangt, die zunächst von Intel vorangetrieben, später aber im Rahmen eines Open-Source-Projekts [9] auch auf anderen Plattformen verfügbar gemacht wurde.
Analog hierzu kann man auch die Integration paralleler Funktionalität (Coarrays, ein SPMD-Modell mit einseitiger Kommunikation für entsprechend annotierte Objekte) in Fortran sehen, die deutlich einfacher als MPI zu handhaben ist und damit potenziell den Entwicklungszyklus für parallele Anwendungen beschleunigen kann, die aber in den anderen HPC-Sprachen nicht oder nur in eingeschränkter Form verfügbar ist.
Der Beschaffungsprozess
Parallelrechner der höchsten Leistungsklasse sind wegen des hohen Investitionsvolumens entsprechend den gesetzlichen Vorschriften über eine europaweite Ausschreibung zu beschaffen. Basis hierfür ist eine detaillierte Spezifikation aller Anforderungen an das Rechensystem. Neben vielen anderen Kriterien lautet eine Anforderung auch, dass der Hersteller eine für die angebotene Architektur optimale Compiler-Suite (Mainline-Compiler) für alle drei klassischen HPC-Sprachen liefert.
Dabei muss der Hersteller den Grad an Standard-Konformität der Implementierungen beschreiben und zudem Angaben bezüglich der Weiterentwicklung der Compiler im geplanten Betriebszeitraum machen. Diese Angaben werden für alle Angebote verglichen und gehen auch in die qualitative Bewertung des jeweiligen Angebots ein.
Die quantitative Bewertung der Angebote bezieht sich im Wesentlichen auf die erzielbare Rechenleistung des Systems. Dabei muss jeder Anbieter für eine im Anforderungskatalog vorab festgelegte Menge von Benchmark-Programmen Leistungsprojektionen für das angebotene System liefern. Diese Benchmarks sind entweder synthetisch und messen dann spezifische System-Aspekte wie Hauptspeicher- oder Netzwerk-Bandbreiten, oder es handelt sich um reale Anwendungen, die auf Programmen beruhen, die auf dem aktuell betriebenen Vorgängersystem laufen. Für die künftig zu erwartenden Problemgrößen skaliert man sie hoch, etwa durch geeignete Vergrößerung der zu verarbeitenden Datensätze.
Im Regelfall sind für das Übersetzen der Rechenprogramme die angebotenen Mainline-Compiler zu benutzen; entsprechend sind in der Benchmark-Suite alle klassischen HPC-Sprachen vertreten. Der Hersteller darf durch geeignete Wahl von Implementierungs-spezifischen Compileroptionen sowie Compilerdirektiven (Pragmas) die Ausführungsgeschwindigkeit optimieren. In der Regel beinhalten solche Optionen auch Hardware-spezifische Optimierungen, wie sie der Artikel weiter unten kurz beschreibt.
In Summe spielt also die Auswahl des Compilers aus Sicht des Anbieters zwar durchaus eine Schlüsselrolle, aber sie geht bei der Bewertung des Systems im Vergleich zu dem eines anderen Herstellers hauptsächlich über die Benchmark-Leistung als Bewertungsschwerpunkt ein. Sprachimplementierungen und Unterstützung von Sprachmerkmalen machen nur einen kleinen Korrekturfaktor aus. Einen minimalen Umfang an Standardunterstützung fordert die Beschaffungs-Spezifikation aber sowohl für die HPC-Sprachen als auch für die begleitenden Programmiermodelle immer verpflichtend ein. Der Umfang wächst zwischen den Systemgenerationen meist an.
Konsequenzen eines Systemwechsels
Ergibt die Prüfung im Zuge einer Ausschreibung, dass das Rechenzentrum auf eine neue Systemarchitektur umsteigen muss, ergeben sich daraus oft erhebliche Konsequenzen für den Betrieb. Zwar garantieren die einschlägigen Standards für HPC-Sprachen, Programmiermodelle und Bibliotheken grundsätzlich die Portierbarkeit der Codebasis auf eine neue Plattform. Dass man damit aber auch wieder dieselbe oder eine bessere Performance erreicht, ist alles andere als selbstverständlich.
Bei jedem Systemwechsel in der Vergangenheit mussten die wissenschaftlichen Projekte daher ihre Programmcodes auf Performance-Schwächen prüfen und – unter Umständen mit Unterstützung des Rechenzentrums – auch noch einmal optimieren.
Bei der Einführung neuerer Architekturen hat sich seit Jahren gezeigt, dass sich das Problem der Performance-Portierbarkeit immer weiter verschärft hat. Egal ob man Many-Core (Intel Xeon Phi) oder GPU-Beschleunigung betrachtet: Von der potenziell sehr hohen Rechenleistung solcher Systeme verliert man im Vergleich zu früher statt eines Bruchteils schnell mehr als eine ganze Größenordnung, wenn die Speicherzugriffsmuster oder der Speicherbedarf der Anwendung nicht genau auf den Sweet Spot der neuen Architektur zugeschnitten sind.
Zum Beispiel sind diskontinuierlich im Speicher liegende Feldelemente auf aktuellen Intel-Prozessoren nicht vektorisierbar, was bei Nutzung aktueller SIMD-Einheiten bis zu einem Faktor 32 an Leistungsverlust nach sich ziehen kann. Ähnlich hohe Leistungsverluste kann der Anwender erleiden, dessen Arbeitsdatensatz nicht vollständig in den relativ kleinen lokalen Hauptspeicher einer Beschleunigerkarte passt. Die Folge sind oft leistungsreduzierende Offload-Datentransfers. So wird der Programmierer gezwungen seine bisher benutzten Datenlayouts zu ändern, was für große Anwendungen sehr aufwändig ist.
Zudem muss er meist neuere Sprachenmerkmale – etwa die erst mit Open MP 4.5 definierten Direktiven für den asynchronen Offload von Daten vom Host-Prozessor auf eine Beschleunigerkarte oder SIMD-Direktiven zur Vektorisierung – nutzen, um die Anwendung überhaupt GPU-fähig beziehungsweise auf Many-Core-Prozessoren vektorisiert zu bekommen. Die effiziente Implementierung dieser Open-MP-Konzepte (oder auch alternativer Modelle wie Open-ACC) in der gewählten Compilersuite ist notwendig, damit die Optimierung gelingt.
Wegen der inzwischen recht hohen Komplexität der Programmiermodelle kann es durchaus – je nach Anwendungsprofil – angezeigt sein, eine Compiler-Alternative zu prüfen. Je nach Plattform bietet das LRZ auf seinen HPC-Systemen eine bis zwei solche Alternativen an.
Infos
- LRZ, HPC-Services: https://www.lrz.de/services/compute
- Fortran: https://wg5-fortran.org
- C++: https://isocpp.org
- C: http://www.open-std.org/jtc1/sc22/wg14
- Super MUC: https://www.lrz.de/services/compute/supermuc
- Gnu Compiler Collection: https://gcc.gnu.org
- Open MP: http://www.openmp.org
- MPI:http://mpi-forum.org
- Thread Building Blocks: https://www.threadingbuildingblocks.org






