Über unsMediaKontaktImpressum
Dr. Jens Breitbart, Dr. Carsten Clauss & Dr. Stefan Lankes 22. August 2017

Virtualisierung und Supercomputing – von Vorbehalten und Vorzügen

Supercomputer sind teuer und das ist einer der Gründe, warum sie meist von staatlichen Institutionen getragen werden. © bluemoon1981 / Fotolia.com
© bluemoon1981 / Fotolia.com

Auch wenn Virtualisierungstechniken heutzutage auf breiter Front in Serverfarmen und im Cloud-Computing eingesetzt werden, konnte sich ihre Verwendung bisher nicht im Bereich des Hoch- und Höchstleistungsrechnens (HPC/Supercomputing) nachhaltig durchsetzen. Als Grund dafür werden immer wieder die Leistungsverluste genannt, die mit der Virtualisierung einhergehen und die bisher im Bereich des HPC als nicht hinnehmbar angesehen wurden. Aktuelle technische Entwicklungen sowie der zunehmende Bedarf nach Fehlertoleranz, Formbarkeit und individuellen Systemumgebungen führen aber derzeit dazu, dass über die vermehrte Einführung von Virtualisierungstechniken auch im Bereich des Supercomputing verstärkt nachgedacht wird.

Supercomputing: Die schnellsten Rechner der Welt

Die meisten Leser dürften mit dem Umgang von Virtualisierungstechniken wie virtuellen Maschinen (VMs) oder Container, durch deren Einsatz zum Beispiel im eigenen Berufsumfeld, bereits hinlänglich vertraut sein. Aber auch wer nicht täglich mit Virtualisierungstechniken arbeitet wird zumindest über deren Bedeutung für Cloud-Computing und Serverfarmen als Motor der modernen IT-Wirtschaft informiert sein. Anders mag es jedoch vielleicht mit den Kenntnissen über die Eigenheiten des wissenschaftlichen Hoch- und Höchstleistungsrechnens aussehen, das primär im akademischen Umfeld wie staatlichen Forschungseinrichtungen und Universitäten angesiedelt ist, und dessen Königsklasse das Supercomputing darstellt.

Tatsächlich fallen in diese Klasse die schnellsten Rechner der Welt – zumindest, wenn sich ihre Betreiber an dem zweimal im Jahr stattfindenden Wettbewerb der Top500-Liste [1] beteiligen. Die aktuelle Liste dieser 500 schnellsten Rechner der Welt ist erst kürzlich im Rahmen der International Supercomputing Conference (ISC) in Frankfurt veröffentlicht worden, enthielt aber wenig Überraschungen: Nach wie vor rangiert China mit zwei Rechnerinstallationen (den Rechnern Sunway TaihuLight mit ca. 125 PFlop/s sowie MilkyWay/Tianhe-2 mit ca. 55 PFlop/s Peak- Performance) in zwei nationalen Supercomputing-Zentren unangefochten auf den ersten beiden Plätzen. Zum Vergleich: der schnellste deutsche Rechner ist derzeit ein Cray-System mit dem Namen Hazel Hen auf Platz 17 der Liste, das am Höchstleistungsrechenzentrum Stuttgart (HLRS) installiert ist und es "lediglich" auf etwa 7 PFlops/s Peak-Performance bringt. Bei der Betrachtung dieser Rangliste ist jedoch zu beachten, dass eben nicht die Peak-Performance als die auf einem Datenblatt aggregierte Rechenleistung aller verbauten CPUs, Cores und sonstigen Recheneinheiten ausschlaggebend ist, sondern dass die tatsächlich mit einem Benchmark gemessene Rechenleistung für die Bewertung herangezogen wird. Dieser Benchmark mit dem Namen High Performance Linpack (HPL) entspringt dabei Problemen der linearen Algebra und löst einfach gesprochen ein großes Gleichungssystem aus Fließkommawerten. Der zu Grunde liegende Algorithmus ist dabei derart parallelisiert, dass möglichst alle Recheneinheiten des Gesamtsystems gemeinsam zu dieser Lösung beitragen.

Wie man sieht, unterscheidet sich diese Art der Verwendung eines Supercomputers deutlich von den verteilten und oft individuellen Aufgaben, die die Rechner zum Beispiel in Serverfarmen zu erledigen haben. Der Grund dafür ist, dass bei der Parallelverarbeitung im HPC alle einzelnen Rechner eines Supercomputers – und um nichts anderes als einen leistungsstarken Verbund (Cluster) von Einzelrechnern (Knoten) handelt es sich üblicherweise hier – gemeinsam an der jeweiligen Aufgabe arbeiten, was aufgrund von Datenabhängigkeiten in der Regel zu einem immensen Kommunikationsaufkommen zwischen den Rechnern und Recheneinheiten eines Supercomputers führt. Diese Tatsache führt wiederum dazu, dass man Supercomputer heutzutage zwar üblicherweise aus standardisierten Serverkomponenten "von der Stange" aufbaut, dass aber die Verbindungen zwischen diesen Komponenten aus Hochleistungsnetzen wie InfiniBand oder OmniPath oder gar aus dediziert entwickelten Supercomputing-Interconnects bestehen. Der Vorteil dieser speziellen Netzwerke liegt neben extrem geringen Kommunikationsverzögerungen (Latenzen) und hohen Datenraten (Bandbreiten) auch in deren Fähigkeit, unabhängig von den jeweiligen CPUs Daten auszutauschen oder gar zu akkumulieren (Remote Direct Memory Access, RDMA).

Zudem legt man im Bereich des Supercomputing besonderen Wert auf Vektorverarbeitung und hierbei insbesondere auf die Fließkommaleistung, wie sie insbesondere von Simulationsanwendungen benötigt werden. So stammen eben auch die klassischen Anwendungen des HPC aus dem Umfeld der wissenschaftlichen Simulation von Fragestellungen zum Beispiel aus den Bereichen der Astrophysik und Teilchenphysik, der Quantenmechanik und Quantenchemie, der Strömungsmechanik, der Klimaforschung, aber auch der Wettervorhersage sowie neuerdings auch der Neurowissenschaften [2]. Zur Steigerung dieser von Simulationen oft benötigten Vektorleistung ist man daher in den letzten Jahren dazu übergegangen, zusätzlich zu den Standardprozessoren GPGPUs (General-Purpose Computing on Graphics Processing Units) oder Xeon-Phis als Acceleratoren zu verbauen, die Supercomputer in ihrer Struktur heterogen oder zumindest modular werden lassen [3] (Modular Supercomputing).

Aufgrund dieser Eigenheiten ist sowohl die Verwendung als auch die Programmierung eines solchen Systems deutlich anders, als man es vielleicht aus anderen Bereichen des gehosteten Rechnens kennt. Zum einen muss der jeweilige Algorithmus (zum Beispiel zum Lösen eines Gleichungssystems wie beim HPL) parallelisiert sein, damit er auf mehreren Rechnern verteilt am Ende zu einer gemeinsamen Lösung führt. Zum anderen muss auch das Problem (im Falle von HPL zum Beispiel die Matrix) über alle beteiligten Recheneinheiten verteilt werden, um dort dann von entsprechend parallel gestarteten Prozessen verarbeitet werden zu können. Als Parallelisierungsparadigma hat sich dabei – neben der lokalen Parallelisierung durch Threads wie zum Beispiel mit OpenMP oder CUDA – das sogenannten Message-Passing Interface (MPI) als dominierender Standard für die softwareseitige Umsetzung des benötigten Nachrichtenaustausches zwischen den parallelen Prozessen etabliert.

Supercomputer sind teuer – sowohl in der Anschaffung als auch im Unterhalt – und auch das ist einer der Gründe, warum solche Installationen zumeist von staatlichen Institutionen getragen werden. Dabei wird normalerweise (außer vielleicht beim HPL-Lauf für das Ranking der Top500-Liste) nie das gesamte System einem einzelnen Nutzer zur Verfügung gestellt, sondern üblicherweise teilen sich mehrere Anwender das System zeitlich (durch Warteschlagen) und räumlich (durch die Einteilung in Partitionen und Allokationen) mithilfe eines Job-Verwaltungssystems. Der Benutzer verzichtet dabei oft ganz bewusst auf jegliche Interaktivität, in dem er seine Rechenaufgabe (sprich: sein Programm zusammen mit den zu verarbeitenden Daten) in Form einer Job-Spezifikation an das Frontend der Job-Verwaltung geschickt – denn interaktive Sitzungen sind aus Effizienzgründen in der Regel nur mit einer eingeschränkten Anzahl an Rechenressourcen zugelassen. Ein in der Job-Verwaltung ebenfalls angesiedelter Scheduler entscheidet anschließend unter Berücksichtigung von Job-Größe, Prioritäten und derzeit freien Ressourcen, wann der Job letztendlich zur Ausführung kommt, um so die Effizienz des Systems zu gewährleisten.

Virtualisierung: verbreitet im Cloud-Computing, verschmäht im HPC?

Abb.1: Rechenleistung von parallelen Algorithmen mit und ohne Virtualisierung. FT: diskrete Fourier-Transformation, BT: Block-Tridiagonal- Löser, LU: Lower-Upper-Gauss-Seidel-Löser. Alle drei Algorithmen sind Teil der NAS Parallel Benchmarks (NPB) Suite, die Pseudo-Anwendungen aus dem Bereich der numerischen Strömungsmechanik darstellen. (Abbildung mit freundlicher Genehmigung von S. Pickartz et al.)
Abb.1: Rechenleistung von parallelen Algorithmen mit und ohne Virtualisierung. FT: diskrete Fourier-Transformation, BT: Block-Tridiagonal- Löser, LU: Lower-Upper-Gauss-Seidel-Löser. Alle drei Algorithmen sind Teil der NAS Parallel Benchmarks (NPB) Suite [5], die Pseudo-Anwendungen aus dem Bereich der numerischen Strömungsmechanik darstellen. (Abbildung mit freundlicher Genehmigung von S. Pickartz et al.)

Dieses ausgeprägte Ringen um Effizienz mag auch einer der Gründe sein, warum man sich im Bereich des Hochleistungsrechnens vor Virtualisierung und ihrem vermeintlichen Overhead bisher merklich scheut. Frei nach dem Motto "Wir fahren hier (im übertragenen Sinne) Formel 1 und haben daher weder Bedarf für eine Fahrzeuginnenraumklimatisierung, noch könnten wir sie uns aus Effizienzgründen leisten", werden die Vorzüge einer virtualisierten Rechenumgebung, wie sie zum Beispiel beim Cloud-Computing geschätzt werden, hier kategorisch ausgeklammert. Dabei werden als Totschlagargument immer wieder die nicht hinnehmbaren Leistungseinbußen genannt, die die Virtualisierung angeblich mit sich brächte.

Dabei sind die Vorzüge wie Sicherheit, Fehlertoleranz und Formbarkeit sehr wohl auch für das Supercomputing von hohem Interesse – und dass die Leistungseinbußen durch Virtualisierung per se immer so gravierend sind, dass sie diese Vorzüge stets annihilieren, ist zumindest des Hinterfragens wert. Tatsächlich haben Untersuchungen gezeigt [4], dass die tatsächlichen Verluste durch die Kapselung der parallelen Rechenprozesse innerhalb von VMs auch bei typischen Algorithmen und Arbeitslasten aus dem HPC-Bereich eigentlich nur marginale Ausmaße haben, wie es auch Abb.1 für drei typische Benchmark-Algorithmen aus dem HPC-Betreich zeigt.

Auch wenn auf Betreiberseite offensichtlich bisher geringes Interesse besteht, diese Leistungsverluste in Abwägung anderer Vorteile und Möglichkeiten in Kauf zu nehmen, so manifestiert sich jedoch derzeit auf Anwenderseite der Wunsch nach mehr Individualisierung der Benutzerumgebungen, wie es zum Beispiel durch den Einsatz von Containern möglich ist. So ist es mit Hilfe von Docker sehr einfach möglich, sich einen personalisierten Container zu erzeugen, der dann eine bevorzugte MPI-Implementierung oder OpenMP-Laufzeitumgebung enthält. Hierdurch können parallele Anwendungen im Kleinen auf einem Desktop-Rechner oder gar Laptop getestet und bis zur Reife entwickelt werden. Anschließend könnte dieser Container mit der entwickelten Anwendung im Großen dann auf einen Supercomputer gebracht werden. Durch diesen Weg wird quasi die Entwicklungsumgebung vom Laptop zum Supercomputer transferiert, was häufig als Bring-Your-Own-Environment (BYOE) bezeichnet wird. Insbesondere für die Anwendungsentwickler ist diese Vorgehensweise äußerst attraktiv, da sie ihre zugeschnittene Umgebung wiederverwenden können. Allerdings unterstützen die meisten Supercomputer kein Docker, da der Daemon zum Initiieren der Container mit Root-Rechten läuft und sicherheitstechnisch zumindest als problematisch gilt. Eine Alternative stellt hier Singularity [6] dar, das als Container-Lösung für Hochleistungsrechnen ohne Spezialrechte auskommt. Zudem bietet es die Möglichkeit an, Docker-Container in das eigene Format umzuwandeln. Somit kann der Entwickler mit seiner bevorzugten Docker-Lösung arbeiten, diese automatisiert in einen Singularity-Container umwandeln und so auf einem Supercomputer starten. Mit Shifter [7] existiert zudem eine weitere Alternative, welche speziell für den Einsatz von Docker im HPC-Umfeld entwickelt wurde.

Diese container-basierten Ansätze erlauben dem Anwender schon einen großen Gestaltungsspielraum für seine jeweils gewünschte Rechenumgebung. Allerdings ist diese Sichtweise beschränkt auf hardwareunabhängige parallele Anwendungen, wie es zum Beispiel thread-basierte Parallelisierungskonzepte ermöglichen. Besteht eine starke Abhängigkeit zwischen Gerätetreiber und Laufzeitumgebung, wie sie beispielsweise bei der GPU-Programmierung vorkommt, kann dies problematisch werden, da Treiber ein Bestandteil des Gastgeberbetriebssystems sind und somit zwischen Entwicklungssystem und Supercomputer unterscheiden können. Eine Voll-Virtualisierung könnte dieses Problem lösen, da beispielsweise mit Single-Root I/O Virtualization (SR-IOV) mehreren virtualisierten Gastbetriebssystemen ein nativer Zugriff auf ein gemeinsam genutztes PCI-e-Gerät ermöglicht wird. Somit können Gastbetriebssysteme ihre passenden Treiber laden, ohne den Gastgeber zu beeinflussen. SR-IOV wird beispielsweise von Mellanox InfiniBand-Karten und teilweise von AMDs Grafikkarten unterstützt.

Vorzüge eines voll-virtualisierten Supercomputing

Ansätze für Voll-Virtualisierung sind auch heute schon in vielen HPC-Rechenzentren vorhanden – jedoch sind es primär nur einzelne Dienste wie zum Beispiel der Job-Scheduler oder die Login-/Admin-Knoten, die stellenweise bereits in VMs gekapselt werden. Unter voll-virtualisiertem Supercomputing soll hier daher insbesondere auch die Kapselung der parallelen Rechenprozesse in VMs verstanden werden, so dass sich virtuelle Cluster in Form von virtuellen Partitionen auf die eigentliche Infrastruktur des HPC-Systems abbilden lassen. Eine virtuelle Partition umfasst somit eine Menge an physischen Knoten, wobei jeder physische Knoten gleichzeitig auch mehreren virtuellen Partitionen zugeordnet sein kann. Zudem muss diese Zuordnung nicht statisch sein, sondern könnte sich gar während des Bestehens der Partition dynamisch ändern. Innerhalb der virtuellen Partitionen werden dann VMs gestartet, die schließlich die eigentlichen Rechenprozesse enthalten. Durch die Möglichkeit der Migration von VMs sind diese dann aber nicht mehr an physische Hostrechner gebunden, sondern können innerhalb der virtuellen Allokation verschoben werden.

Wie man an diesen Überlegungen bereits erkennt, bietet gerade die Fähigkeit zur Live-Migration von VMs bisher unbekannte Möglichkeiten für die Formbarkeit (Malleability) beim Job-Scheduling in Supercomputern. Zudem kommt durch die Kapselung und den damit entstehenden Schutz der Prozesse durch die VMs ein Co-Scheduling in Betracht, bei dem sich mehrere Prozesse verschiedener Anwender ein und denselben physischen Hostrechner teilen (Node Sharing). Wie sehr dieser Ansatz sich zur Effizienzsteigerung einsetzen lässt, wird in diesem Artikel später noch ausführlicher diskutiert.

Vorteil: Fehlertoleranz und Robustheit

Ein weiterer Aspekt, der zukünftig neben der allgemeinen Frage nach Effizienzsteigerungen im Supercomputing immer wichtiger werden wird, ist der steigende Bedarf an Fehlertoleranz (Resiliency). Hat man in der aktuell andauernden PetaFLOPS-Ära noch etwa O(10k) Rechenknoten in HPC-Systemen, so werden es in der zukünftigen ExaFLOPS-Ära schon O(100k) bis O(1.000k) Rechenknoten sein. Wie häufig hier Teile des Systems ausfallen werden, kann man sich durch folgende Überlegung veranschaulichen: Man nehme an, dass ein einzelner physischer Rechenknoten im Schnitt alle 50 Jahre (MTBF = 50 a) durch einen Defekt ausfällt – was hier willkürlich gewählt, aber trotzdem schon sehr hochgegriffen ist. In Abhängigkeit der Anzahl der verbauten Einzelrechner ergeben sich dann zum Beispiel folgende Ausfallraten bezogen auf das Gesamtsystem:

  • bei 10.000 Rechenknoten: Ausfall eines Knotens etwa alle 1,75 Tage

  • bei 100.000 Rechenknoten: Ausfall eines Knotens etwa alle 4,4 Stunden
  • bei 1.000.000 Rechenknoten: Ausfall eines Knotens etwa alle 26 Minuten

Wenn man davon ausgeht, dass der Bedarf an Rechenleistung durch die Anwender sich nicht sättigen wird – so war es zumindest bisher seit den Anfängen des wissenschaftlichen Hochleistungsrechnens – dann werden bei den heute üblichen Job-Laufzeiten von oftmals mehreren Stunden in der Zukunft keine großen Jobs bei gleichen Laufzeiten mehr ohne Fehlertoleranz auskommen. Neben einer programmierten Robustheit in den Algorithmen selbst, bieten zum Beispiel Checkpoint/Restart-Mechanismen hier einen guten Ansatz, um bereits berechnete Ergebnisse nicht durch einen Ausfall zu verlieren.

Wie man sieht, ließe sich auch hier mit dem Einsatz von VMs ganz transparent für den Programmierer und/oder Anwender durch das zyklische Anlegen von Sicherungspunkten aller VMs eines Jobs ein deutlicher Mehrwert generieren. Zudem wäre zusätzlich zu einem solchen Sicherungspunktverfahren auch die proaktive Migration vor drohenden Knotenausfällen durchaus denkbar. So hat die Firma ParTec zum Beispiel einen HealthChecker [8] in ihrem HPC-Software-Portfolio, der unter anderem im Supercomputing Centre des Forschungszentrum Jülich vor jedem Job-Start anhand diverser Kriterien den Gesundheitszustand der zuzuteilenden Rechenknoten überprüft und suspekte Knoten dabei aussortiert. Mit einer zyklischen Fortführung dieser Gesundheitsprüfung auch zur Laufzeit könnten so die Rechenprozesse bei drohenden Ausfällen rechtzeitig mit ihren VMs "wegmigriert" werden.

An dieser Stelle soll aber nicht verschwiegen werden, dass sich sowohl das Anlegen von Sicherungspunkten als auch das Migrieren von Prozessen in Supercomputing-Umgebungen leider nicht so trivial umsetzen lässt, wie es die obigen Ausführungen und die gewöhnlichen Erfahrungen im Umgang mit VMs vielleicht vermuten lassen. Der Grund dafür ist, dass es zum Erstellen eines konsistenten Sicherungspunktes über alle parallelen Prozesse eines virtuellen Clusters eben nicht ausreicht, einfach alle entsprechenden VMs zu sichern, da zwischen diesen Nachrichten unterwegs sein könnten, die ebenfalls zum augenblicklichen Zustand der Sitzung dazu gehören. Ohne das Mitsichern dieser Daten im Netz ließe sich nach einem Ausfall kein sinnvolles Wiederaufsetzen (Rollback) auf dem letzten Sicherungspunkt durchführen.

Diese Datenabhängigkeiten zwischen den parallelen Prozessen – und somit zwischen den VMs – führen daher dazu, dass zum Schreiben eines parallelen Sicherungspunktes zum einen eine Synchronisation der Prozesse angebracht ist, und dass zum anderen entweder die ausstehenden Daten im Netz mitgesichert werden – oder aber, dass man sicherstellt, dass sich zum Zeitpunkt der Sicherung einfach keine ausstehenden Daten mehr im Netz befinden. Gleiche Überlegungen treffen im Übrigen auch auf eine VM zu, die migriert werden soll, in Bezug auf die mit ihr verbundenen Partner-VMs der parallelen Sitzung.

Ohne zu sehr auf die Details einzugehen, sei an dieser Stelle erwähnt, dass bei der Verwendung von ARQ-Protokollen wie TCP zur Kommunikation zwischen den Prozessen eine Sicherung der ausstehenden Daten durch die Flusskontrolle (Sliding Window) schon implizit gegeben ist, wohingegen bei RDMA-Netzen, wie sie in HPC-Systemen häufig verbaut werden, derzeit nur ein Leeren der Kommunikationskanäle zu einem konsistenten Zustand für einen Sicherungspunkt oder die VM-Migration führt. MPI-Bibliotheken, die dies derzeit für RDMA-Netze wie InfiniBand unterstützen, sind zum Beispiel MVAPICH2-Virt [9] und ParaStation MPI [10].

Die MPI-Bibliotheken werden dazu von außen informiert, dass die betroffenen RDMA-Verbindungen geschlossen werden sollen. Daraufhin wird von ihnen jegliche weitere Kommunikation auf diesen Kanälen zurückgehalten, bis sich dort keine Daten mehr im Transfer befinden. Nach einer anschließenden Rückmeldung wird dann über ein Hot-Plug-Event für die VM die vorher über SR-IOV durchgereichte Netzwerkkarte softwareseitig entfernt und der Sicherungspunkt oder die Migration können sicher durchgeführt werden.

Vorteil: Formbarkeit und Co-Scheduling

Nach einer gängigen Taxonomie [11] teilt man – zumindest in der Theorie – die verschiedenen möglichen Job-Typen sowie die entsprechenden Zuteilungsverfahren (Job-Scheduling) je nach Grad ihrer Flexibilität und Formbarkeit in folgende Kategorien ein:

Jobtypen:

  • Rigid Jobs: Der auszuführende parallele Algorithmus benötigt eine bestimmte feste Anzahl an Rechenknoten/Prozessoren/Ausführeinheiten, damit er ausgeführt werden kann. Ein Beispiel hierfür wäre ein festcodiertes Parallelisierungsschema im Algorithmus, das von einer exakten Anzahl an parallelen Rechenprozessen ausgeht.

  • Moldable Jobs: Der Algorithmus eines solchen Jobs ist dahingehend flexibel, als dass er sich aufgrund seines Parallelisierungsschema mit verschiedenen Anzahlen an Rechenprozessen ausführen lässt. Der Scheduler kann dann – eventuell unter Berücksichtigung einer Mindestanzahl – zur Startzeit des Jobs diesem eine möglichst optimale Anzahl an freien Rechenressourcen zur Verfügung stellen.
  • Evolving Jobs: Hier kann der Job selbst zur Laufzeit weitere Ressourcen anfordern, da zum Beispiel ein paralleler Devide-and-Conquer- Algorithmus neue Prozesse auf weitere Rechenknoten verteilen möchte. Diese dynamische Ressourcenanforderung und -freigabe wird dabei also vom Algorithmus selber getriggert.

  • Malleable Jobs: Auch hier werden Rechenressourcen dynamisch zur Laufzeit eines Jobs zugeteilt und eventuell wieder entzogen. Jedoch ist es hier der Scheduler, der diese Ereignisse triggert, und nicht der Algorithmus. Dieser muss jedoch wiederum in der Lage sein, mit solchen aufgezwungenen Entscheidungen des Schedulers zur Laufzeit auch umgehen zu können.

Zuteilungsverfahren:

  • Space Slicing (flexible Partitionierung): Hiermit ist gemeint, dass sich die Menge aller Rechenressourcen beliebig vom Scheduler in Portionen einteilen und dann verschiedenen Jobs zuteilen lässt. Während bei Rigid und Moldable Jobs eine statische Partitionierung zum Einsatz kommt, müssten/dürften sich für Evolving und Mallebale Jobs die Partitionsgrößen auch dynamisch verändern lassen.

  • Time Slicing (Zeitscheibenverfahren): Hier wird jedem Job nur eine gewisse Laufzeit in Form einer Zeitscheibe zugeteilt. Ist diese Zeitscheibe abgelaufen, ohne dass der Job in dieser fertiggestellt wurde, wird der Job durch den Scheduler explizit abgebrochen. So limitieren zum Beispiel einige Supercomputing-Zentren die Job-Laufzeiten im Standardfall auf 24 Stunden, um unnötigen Ressourcenverbrauch durch hängende Jobs zu vermeiden.
  • Preemption (Unterbrechung): Mit der Möglichkeit, einen laufenden Job sauber zu unterbrechen und später wieder fortzusetzen – wie es zum Beispiel auch mit explizitem Checkpoint/Restart durchführbar ist – ließen sich zum einen Jobs mit einer höheren Priorität auch im Nachhinein noch vorziehen, zum anderen ließe sich so aber auch die Unterbrechung laufender Jobs zu Wartungszwecken (von Teilen) des HPC-Systems elegant durchführen.
  • Migration: Wie bereits ausgeführt bedeutet die Fähigkeit zur Migration für ein Scheduling-System die Möglichkeit, die Prozesse eines Jobs zur Laufzeit zwischen den Rechenknoten des Supercomputers zu verschieben, und stellt somit ein sehr mächtiges Werkzeug zur dynamischen Anpassung von bereits erfolgten Zuteilungen dar.

Wenn man sich diese Taxonomien ansieht, so stellt man fest, dass in heutigen HPC-Umgebungen sowohl bei den Jobtypen als auch bei den Zuteilungsverfahren eigentlich nur die jeweils ersten beiden Kategorien auf breiter Front umgesetzt werden. Während es zur Realisierung von Evolving und Malleable Jobs einer starken und expliziten Verzahnung zwischen den parallelen Algorithmen und dem Job-Scheduler bedarf, ließen sich Preemption und Migration bei den Zuteilungsverfahren relativ einfach und transparent mithilfe von Virtualisierung implementieren.

Abb.2: Laufzeiten eines parallelen Jobs (verteilt auf zwei Rechenknoten) unter dem Einfluss einer anstehenden Wartung eines der Knoten für verschiedene Scheduling-Mechanismen. (Mit freundlicher Genehmigung von S. Pickartz et al. [12])
Abb.2: Laufzeiten eines parallelen Jobs (verteilt auf zwei Rechenknoten) unter dem Einfluss einer anstehenden Wartung eines der Knoten für verschiedene Scheduling-Mechanismen. (Mit freundlicher Genehmigung von S. Pickartz et al. [12])

Das Beispiel in Abb.2 zeigt sehr anschaulich, wie sich mithilfe der beiden letzten Verfahren bei einer notwendig gewordenen Wartung eines Rechenknotens die Systemeffizienz deutlich steigern ließe: Während im ersten Fall (Job Abort and Restart) die bereits berechneten Zwischenergebnisse des Jobs zur Wartung verworfen werden, wird im zweiten Fall der Job über Preemption pausiert und nach Abschluss der Wartung wieder fortgesetzt (Checkpoint/Restart). Noch effizienter als diese zweite Variante stellt sich schließlich Variante drei (Evacuation of Node 1) dar, bei der die Prozesse des Jobs, die auf dem zu wartenden Knoten 1 laufen, einfach auf Knoten 0 migriert werden. Trotz Überbuchung der Recheneinheiten führt die Fortsetzung des Jobs hier zur kürzesten Laufzeit – kürzer ist die Laufzeit nur im vierten Fall, bei dem gar keine Wartung stattfindet.

Bei der hier betrachteten Überbuchung im Falle der Migration wurde davon ausgegangen, dass auf Knoten 0 bereits alle Prozessoren bzw. Rechenkerne vorher mit Prozessen desselben Jobs belegt waren. Klassischerweise vermeidet man im HPC solche Überbuchungssituationen, obwohl eine 100%ige Überbuchung nicht zwangsläufig zu einer doppelten (oder gar noch höheren) Laufzeit führen muss. Der Grund für Letzteres ist, dass auch bei parallelen Anwendungen nicht immer alle Prozesse zu einem Zeitpunkt denselben Ressourcenbedarf haben, und dass es so durch die Überbuchung zu einer besseren Ressourcenauslastung kommen kann – wie es auch in Abb.2 zusehen ist: Obwohl die Wartung (und damit die Überbuchungssituation bei Migration) in diesem Beispiel etwa 20 Minuten dauert, hat sich die Gesamtlaufzeit im dritten Fall nur um etwa 8,5 Minuten gegenüber dem wartungslosen Fall verlängert.

IT-Tage 2017 - Big Data
Abb.3: Beispiel eines Co-Scheduling-Szenarios mit Migration (unten) im Vergleich zum klassischen Ansatz ohne Node-Sharing (oben). (Mit freundlicher Genehmigung von S. Pickartz et al.)
Abb.3: Beispiel eines Co-Scheduling-Szenarios mit Migration (unten) im Vergleich zum klassischen Ansatz ohne Node-Sharing (oben). (Mit freundlicher Genehmigung von S. Pickartz et al. [12])

Diesem Ansatz folgend kann es auch sehr lohnenswert sein, Anwendungen mit verschiedenen Ausprägungen des Ressourcenbedarfs auf ein und dieselben Rechenknoten im Sinne eines Co-Scheduling zu platzieren. Auch wenn es hierbei nicht zwangsläufig zu einer Überbuchung der Prozessoren kommt, so können die verschiedenen Charakteristika der Jobs zu einer besseren Ressourcenauslastung führen, die auch wiederum die Laufzeit der Jobs positiv beeinflussen kann. Abb.3 zeigt ein Beispiel, bei dem zwei HPC-Anwendungen einmal getrennt und einmal gemeinsam auf zwei Rechenknoten (jeweils bestückt mit 16 Prozessorkernen) zur Ausführung gebracht werden, wobei in beiden Fällen zunächst nur eine der beiden Anwendungen auf einem Rechenknoten läuft. Sobald auch die zweite Anwendung gestartet werden soll, muss das Scheduling-System entscheiden, ob diese auf dem noch leeren Knoten (klassischer Fall) oder durch Teilmigration von Prozessen der ersten Anwendung im Co-Scheduling-Betrieb zusammen mit dieser auf beiden Knoten ausgeführt werden soll. Im vorliegenden Fall, bei dem beide Anwendungen deutlich unterschiedliche Charakteristika haben – mpiBLAST ist rechenintensiv (compute-bound) und SP hingegen speicherintensiv (memory-bound) – ist offensichtlich der Co-Scheduling-Ansatz vorzuziehen.

Wie sich solche Charakteristika von Anwendungen, die sich durchaus auch dynamisch ändern können, zur Laufzeit dieser feststellen lassen, und wie sich auf Basis dieser Ergebnisse neue Scheduling-Entscheidungen treffen und umsetzen lassen, wurde bereits ausgiebig in dem vom BMBF geförderten FAST-Projekt [13] (Find a Suitable Topology for Exascale Applications) untersucht. Zur Realisierung der in diesem Projekt benötigten Prozessmigration wurde dabei ebenfalls auf den Einsatz von Virtuellen Maschinen zurückgegriffen und große Teile der in diesem Artikel dargestellten Erkenntnisse stammen aus dem Umfeld dieses Projektes.

Fazit

Container aber auch volle Virtualisierung sind insbesondere im Cloud-Computing etablierte Techniken. Im Bereich des Hochleistungsrechnens werden diese Techniken nur vereinzelt angewandt, obwohl sie eine deutlich höhere Flexibilität anbieten, aber auch neue Geschäftsmodelle (HPC as a Service) ermöglichen würden. Zu sehr lastet der Ruf, einen zu hohen Overhead zu erzeugen. Zudem müssen bei der Voll-Virtualisierung zwei Betriebssysteme beherrscht werden. Einfache Optimierungstricks, wie das Binden von Threads an einen Prozessor, um das Wandern der Threads zwischen den CPUs zu verhindern, müssen nun sowohl beim Gastgeber- als auch Gastbetriebssystem durchgeführt werden, um die bestmögliche Leistung zu erzielen. Dies verkompliziert das Beherrschen des Systems.

Trotzdem werden Virtualisierungstechniken zunehmend auch für HPC attraktiv, da die Vorteile überwiegen und die Nachteile beherrschbar sind. Es wird spannend zu sehen sein, wie die Systemsoftware sich für solche Systeme entwickeln wird. Insbesondere bei der vollen Virtualisierung wird die Rolle eines klassischen Betriebssystems als Gastbetriebssystem überflüssig, wenn nur eine (HPC-)Anwendung in der VM läuft. Es stellt sich die Frage: Warum ist in diesem Fall ein volles Mehr-Benutzer- und gleichzeitig ein Mehr-Prozess-Betriebssystem notwendig? Im Bereich des Cloud-Computing gibt es Bestrebungen, dieses durch sogenannte Single-Address-Space Operating Systems zu ersetzen, welche als Unikernels [14] bezeichnet werden. In diesem Fall wird einer Anwendung die (virtuelle) Maschine exklusive zugewiesen, um so den Overhead eines vollen Betriebssystems zu reduzieren. Mit HermitCore [15] gibt es ein erstes Projekt, um diese Technik auch für das Hochleistungsrechnen umzusetzen.

Quellen
  1. Top500.org: Liste der 500 schnellsten Rechner der Welt

  2. Forschungzentrum Jülich: Das Human Brain Project
  3. Forschungzentrum Jülich: Modulares Supercomputing
  4. Pickartz et al. (2014): Migration Techniques in HPC Environments
  5. NASA Advanced Supercomputing: Die NAS Parallel Benchmarks (NPB) Suite  
  6. Lawrence Berkeley National Laboratory: Singularity

  7. National Energy Research Scientific Computing Center: Shifter

  8. ParTec/ParaStation: HealthChecker
  9. The Ohio State University: MVAPICH2-Virt

  10. ParTec/ParaStation: ParaStation MPI

  11. D. Feitelson und L. Rudolph (1996): Toward Convergence in Job Schedulers for Parallel Supercomputers
  12. S. Pickartz et al. (2016): Application Migration in HPC—A Driver of the Exascale Era?

  13. Bundesministerium für Bildung und Forschung: Das FAST-Projekt
  14. Unikernels: Übersicht aller Unikernels
  15. A Unikernel for Extreme-Scale Computing: HermitCore
nach Oben
Autoren

Dr. Jens Breitbart

Dr. Jens Breitbart arbeitet als Softwarearchitekt bei Driver Assistance, Robert Bosch GmbH. Er forschte fast 10 Jahre im Bereich des High Performance Computing.
>> Weiterlesen

Dr. Carsten Clauß

Dr. Carsten Clauß war langjähriger Mitarbeiter am Lehrstuhl für Betriebssysteme der RWTH Aachen University und forschte dort im Bereich des Message-Passing für Manycore-Systeme.
>> Weiterlesen

Dr. Stefan Lankes

Dr. Stefan Lankes war langjähriger Mitarbeiter am Lehrstuhl für Betriebssysteme der RWTH Aachen University und forschte dort im Bereich der Systemsoftware für Manycore-Systeme.
>> Weiterlesen
botMessage_toctoc_comments_929