Automatische Parallelisierung
Automatische Parallelisierung, Auch automatische Parallelisierung, oder Autoparallelisierung bezieht sich auf die Konvertierung sequentielles Code hinein Multi-Threaded und/oder vektorisiert Code, um mehrere Prozessoren gleichzeitig in einem gemeinsam genutzten Memory zu verwenden Multiprozessor (SMP) Maschine.[1] Die vollautomatische Parallelisierung sequentieller Programme ist eine Herausforderung, da sie komplex benötigt Programmanalyse und der beste Ansatz kann von Parameterwerten abhängen, die zur Kompilierungszeit nicht bekannt sind.[2]
Die Programmierkontrollstrukturen, auf denen die Autoparallelisierung am stärksten liegt Schleifen, weil im Allgemeinen die meisten der Ausführungszeit eines Programms findet in einer Form von Schleife statt. Es gibt zwei Hauptansätze zur Parallelisierung von Schleifen: Pipelined Multi-Threading und cyclisches Multi-Threading.[3] Betrachten Sie beispielsweise eine Schleife, die bei jeder Iteration hundert Operationen anwendet und für tausend Iterationen ausgeführt wird. Dies kann als Gitter von 100 Säulen durch 1000 Zeilen, insgesamt 100.000 Operationen, betrachtet werden. Cyclic Multi-Threading weist jede Zeile einem anderen Thread zu. Pipelined Multi-Threading weist jeder Spalte einem anderen Faden zu.
Automatische Parallelisierungstechnik
Analysieren
Dies ist die erste Stufe, in der der Scanner die Eingabefieldateien liest, um alle statischen und externen Verwendungen zu identifizieren. Jede Zeile in der Datei wird mit vordefinierten Mustern überprüft, in die sie getrennt sind Token. Diese Token werden in einer Datei gespeichert, die später von der Grammatikmotor verwendet wird. Die Grammatikmotor überprüft Muster von Token, die mit vordefinierten Regeln übereinstimmen, um Variablen, Schleifen, Steuerungsanweisungen, Funktionen usw. im Code zu identifizieren.
Analysieren
Das Analysator wird verwendet, um Codeabschnitte zu identifizieren, die gleichzeitig ausgeführt werden können. Der Analysator verwendet die vom Scanner-Parser bereitgestellten statischen Dateninformationen. Der Analysator wird zuerst alle völlig unabhängigen Funktionen finden und sie als individuelle Aufgaben markieren. Der Analysator stellt dann fest, welche Aufgaben Abhängigkeiten haben.
Zeitlicher Ablauf
Das Planer Listet alle Aufgaben und ihre Abhängigkeiten in Bezug auf Ausführung und Startzeiten auf. Der Scheduler erstellt den optimalen Zeitplan in Bezug auf die Anzahl der zu verwendenden Prozessoren oder die Gesamtausführungszeit für die Anwendung.
Codegenerierung
Das Planer generiert eine Liste aller Aufgaben und Details der Kerne, für die sie ausführen werden, zusammen mit der Zeit, für die sie ausgeführt werden. Der Codegenerator fügt spezielle Konstrukte in den Code ein, der während der Ausführung vom Scheduler gelesen wird. Diese Konstrukte unterweisen den Scheduler, welcher Kern eine bestimmte Aufgabe zusammen mit den Start- und Endzeiten ausführen wird.
Cyclic Multi-Threading
Ein zyklischer multi-threading-parallelisierender Compiler versucht es zu Teilen Sie eine Schleife auf so dass jeweils Wiederholung kann auf einem separaten ausgeführt werden Prozessor gleichzeitig.
Compiler -Parallelisierungsanalyse
Das Compiler Führen Sie normalerweise zwei Analysedurchgänge vor der tatsächlichen Parallelisierung durch, um Folgendes zu bestimmen:
- Ist es sicher, die Schleife zu parallelisieren? Die Beantwortung dieser Frage erfordert genau Abhängigkeitsanalyse und Alias -Analyse
- Lohnt es sich, es zu parallelisieren? Diese Antwort erfordert eine zuverlässige Schätzung (Modellierung) der Programmarbeit und die Kapazität des parallelen Systems.
Der erste Durchgang des Compilers führt a Datenabhängigkeitsanalyse der Schleife, um festzustellen, ob jede Iteration der Schleife unabhängig von den anderen ausgeführt werden kann. Die Datenabhängigkeit kann manchmal behandelt werden, kann jedoch zusätzlichen Aufwand in Form von NachrichtenübergangSynchronisation von geteilte Erinnerung, oder eine andere Methode der Prozessorkommunikation.
Der zweite Pass versucht, den Parallelisierungsaufwand zu rechtfertigen, indem die theoretische Ausführungszeit des Codes nach der Parallelisierung mit der sequentiellen Ausführungszeit des Codes verglichen wird. Etwas kontraintuitiv profitiert Code nicht immer von der parallelen Ausführung. Der zusätzliche Overhead, der mit der Verwendung mehrerer Prozessoren zugeordnet werden kann, kann in die potenzielle Beschleunigung des parallelisierten Codes essen.
Beispiel
Eine Schleife wird als DOALL bezeichnet, wenn alle Iterationen in einem bestimmten Aufruf gleichzeitig ausgeführt werden können.
Das Forran Der folgende Code ist doall und kann von einem Compiler automatisch parallelisiert werden, da jede Iteration unabhängig von den anderen und das Endergebnis von Array ist z
wird unabhängig von der Ausführungsreihenfolge der anderen Iterationen korrekt sein.
tun i = 1, n z(i) = x(i) + y(i) Enddo
Es gibt viele angenehm parallel Probleme, die solche Doall -Schleifen haben. Zum Beispiel wenn Rendering Ein von Strahlen versehener Film, jeder Rahmen des Films kann unabhängig voneinander gerendert werden, und jedes Pixel eines einzelnen Rahmens kann unabhängig gerendert werden.
Andererseits kann der folgende Code nicht automatisch parallelisiert werden, weil der Wert von z (i)
hängt vom Ergebnis der vorherigen Iteration ab, z (i - 1)
.
tun i = 2, n z(i) = z(i - 1)*2 Enddo
Dies bedeutet nicht, dass der Code nicht parallelisiert werden kann. In der Tat entspricht es der Doall -Schleife
tun i = 2, n z(i) = z(1)*2**(i - 1) Enddo
Aktuelle parallelisierende Compiler sind jedoch normalerweise nicht in der Lage, diese Parallelitäten automatisch herauszubringen, und es ist fraglich, ob dieser Code überhaupt von einer Parallelisierung profitieren würde.
Pipelined Multi-Threading
Ein pipelinierter Multi-Threading-Parallelisierungs-Compiler versucht, die Abfolge von Operationen in einer Schleife in eine Reihe von Codeblöcken zu zerlegen, sodass jeder Codeblock auf separat ausgeführt werden kann Prozessoren gleichzeitig.
Es gibt viele angenehm parallele Probleme, die so relativ unabhängige Codeblöcke haben, insbesondere Systeme Rohre und Filter.
Zum Beispiel müssen bei der Herstellung von Live -Broadcast -Fernsehen die folgenden Aufgaben viele Male eine Sekunde ausgeführt werden:
- Lesen Sie einen Rahmen von Rohpixeldaten aus dem Bildsensor,
- MPEG machen Bewegungskompensation auf den Rohdaten,
- Entropie komprimieren die Bewegungsvektoren und andere Daten,
- Teilen Sie die komprimierten Daten in Pakete auf,
- Fügen Sie die entsprechende Fehlerkorrektur hinzu und führen Sie eine FFF durch, um die Datenpakete in die Umwandlung zu Cofdm Signale und
- Senden Sie die COFDM -Signale aus der TV -Antenne.
Ein pipelinierter Multi-Threading-Parallelisierungs-Compiler könnte jedem dieser sechs Operationen einem anderen Prozessor zuweisen, der möglicherweise in a angeordnet ist systolisches ArrayEinfügen des entsprechenden Codes, um die Ausgabe eines Prozessors an den nächsten Prozessor weiterzuleiten.
Jüngste Forschungen konzentrieren sich auf die Nutzung der Kraft von GPUs[4] und Multicore -Systeme[5] Berechnung solcher unabhängigen Codeblöcke (oder einfach unabhängigen Iterationen einer Schleife) zur Laufzeit. Der auf den Speicher zugegriffene Speicher (ob direkt oder indirekt) kann einfach für verschiedene Iterationen einer Schleife markiert und für die Abhängigkeitserkennung verglichen werden. Mit diesen Informationen werden die Iterationen in Stufen gruppiert, sodass Iterationen, die zu derselben Ebene gehören, unabhängig voneinander sind und parallel ausgeführt werden können.
Schwierigkeiten
Die automatische Parallelisierung durch Compiler oder Tools ist aus folgenden Gründen sehr schwierig:[6]
- Die Abhängigkeitsanalyse ist für Code schwierig, der indirekte Adressierungs-, Zeiger-, Rekursions- oder indirekte Funktionsaufrufe verwendet, da es schwierig ist, solche Abhängigkeiten zum Kompilierungszeit zu erkennen.
- Schleifen haben eine unbekannte Anzahl von Iterationen;
- Zugriffe auf globale Ressourcen sind in Bezug auf Speicherzuweisung, E/O und gemeinsame Variablen schwer zu koordinieren.
- unregelmäßige Algorithmen Dadurch werden die Eingabe-abhängige Indirektion analysiert und die Kompilierungszeitanalyse und -optimierung.[7]
Problemumgehung
Aufgrund der inhärenten Schwierigkeiten bei der vollständigen automatischen Parallelisierung gibt es mehrere einfachere Ansätze, um ein paralleles Programm in höherer Qualität zu erhalten. Eine davon besteht darin, den Programmierern zu ermöglichen, ihren Programmen "Hinweise" hinzuzufügen, um die Compiler -Parallelisierung zu leiten, wie z. HPF zum Verteilter Speicher Systeme und OpenMP oder OpenHMPP zum geteilte Erinnerung Systeme. Ein anderer Ansatz besteht darin, ein interaktives System zwischen Programmierern und parallelisierenden Tools/Compilern aufzubauen. Bemerkenswerte Beispiele sind VektorstoffePareon, Suif Der Explorer (der Intermediate -Format -Compiler der Stanford University), der Polaris Compiler und Parawise (formell Captools). Schließlich ist ein anderer Ansatz hardware unterstützt Spekulatives Multithreading.
Parallelen Compiler und Werkzeuge
Die meisten Forschungen Compiler Für die automatische Parallelisierung berücksichtigen Forran Programme, weil Forran stärker Garantien darüber leisten Aliasing als Sprachen wie z. C. Typische Beispiele sind:
Siehe auch
- Schleifennestoptimierung
- Polytope -Modell Auch als polyedrisches Modell bekannt
- Skalierbare Parallelität
- BMDFM
- Vektorisation
- Sequencel
Verweise
- ^ Yehezkael, Rafael (2000). "Experimente zur Trennung von Rechenalgorithmus von Programmverteilung und Kommunikation" (PDF). Paralleles Computer angewendet. Neue Paradigmen für HPC in Industrie und Akademie. Vorlesungsnotizen in Informatik. Vol. 1947. Springer Verlag. S. 268–278. doi:10.1007/3-540-70734-4_32. ISBN 978-3-540-41729-3.
- ^ Fox, Geoffrey; Williams, Roy; Messina, Paul (1994). Parallele Computing funktioniert!. Morgan Kaufmann. S. 575, 593. ISBN 978-1-55860-253-3.
- ^ Campanoni, Simone; Jones, Timothy; Holloway, Glenn; Wei, Gu-yeon; Brooks, David (2012). Das Helix -Projekt: Übersicht und Anweisungen.
- ^ Anantpur, J.; Govindarajan, R. "Berechnung der Laufzeitabhängigkeit und Ausführung von Schleifen auf heterogenen Systemen" (PDF). Archiviert von das Original (PDF) am 6. Oktober 2015. Abgerufen 5. Oktober 2015.
- ^ Zhuang, X.; Eichenberger, A. E.; Luo, Y.; O'Brien, Kathryn Kevin, Parallelität mit abhängig bewusstes Planen ausnutzen
- ^ "Automatische Parallelität und Datenabhängigkeit". Archiviert von das Original am 14. Juli 2014.
- ^ Rünger, Gudula (2006). "Parallele Programmiermodelle für unregelmäßige Algorithmen". Parallelalgorithmen und Cluster -Computing. Vorlesungen in Computerwissenschaft und -technik. 52: 3–23. doi:10.1007/3-540-33541-2_1. ISBN 978-3-540-33539-9.
Weitere Lektüre
- Pountain, Dick (Dezember 1989). "Konfigurieren paralleler Programme, Teil 1: Der jetzt in der Entwicklung befindliche Occam -Transpiler erleichtert das Schreibsoftware für die parallele Verarbeitung". BYTE. Vol. 14, nein. 13. McGraw-Hill, Inc. S. 349–352. ISSN 0360-5280. Ark:/13960/t34188734. Abgerufen 6. Januar 2022. (NB. Verwendet den Begriff Occam Transpiler als Synonym für a Source-to-Source-Compiler Arbeiten wie a Präprozessor das braucht normal occam Programm als Eingabe programmieren und einen neuen Occam-Quellcode als Ausgabe mit Link-to-Channel-Zuordnungen usw. abgeleitet Konfigurieren es für Parallelverarbeitung in einem Netzwerk von so effizient wie möglich laufen transputers.))