Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieses Dokument gibt eine Auflistung von Compilerdirektiven, Bibliotheksfunktionen und Umgebungsvariablen an, mit denen Sie in C- und C++-Programmen die Parallelität für gemeinsam genutzten Arbeitsspeicher angeben können. Die in diesem Dokument beschriebene Funktionalität wird gemeinsam als OpenMP C/C++-Anwendungsprogrammschnittstelle (API) bezeichnet. Ziel dieser Spezifikation ist es, ein Modell für die parallele Programmierung bereitzustellen, das es einem Programm ermöglicht, über gemeinsame Speicherarchitekturen von verschiedenen Anbietern hinweg portierbar zu sein. Compiler von vielen Anbietern unterstützen die OpenMP C/C++-API. Weitere Informationen zu OpenMP, einschließlich der OpenMP Fortran Application Program Interface, finden Sie auf der folgenden Website:
Die in diesem Dokument definierten Direktiven, Bibliotheksfunktionen und Umgebungsvariablen ermöglichen es Ihnen, parallele Programme zu erstellen und zu verwalten und gleichzeitig die Portabilität zu ermöglichen. Die Direktiven erweitern das sequenzielle C- und C++-Programmiermodell mit einzelnen Programm-Multiple Data (SPMD)-Konstrukten, Arbeitsfreigabekonstrukten und Synchronisierungskonstrukten. Sie unterstützen auch die Freigabe und Privatisierung von Daten. Compiler, die die OpenMP C- und C++-API unterstützen, enthalten eine Befehlszeilenoption für den Compiler, der die Interpretation aller OpenMP-Compilerdirektiven aktiviert und ermöglicht.
1.1 Bereich
Diese Spezifikation behandelt nur benutzergesteuerte Parallelisierung, wobei Sie explizit definieren, welche Aktionen der Compiler und das Laufzeitsystem ausführen, um das Programm parallel auszuführen. OpenMP C- und C++-Implementierungen sind nicht erforderlich, um auf Abhängigkeiten, Konflikte, Deadlocks, Racebedingungen oder andere Probleme zu überprüfen, die zu einer falschen Programmausführung führen. Sie sind dafür verantwortlich, sicherzustellen, dass die Anwendung, die die OpenMP C- und C++-API-Konstrukte verwendet, ordnungsgemäß ausgeführt wird. Compilergenerierte automatische Parallelisierung und Direktiven zum Compiler zur Unterstützung einer solchen Parallelisierung werden in diesem Dokument nicht behandelt.
1.2 Definition der Begriffe
Die folgenden Begriffe werden in diesem Dokument verwendet:
Barriere
Ein Synchronisierungspunkt, den alle Threads in einem Team erreichen müssen. Jeder Thread wartet, bis alle Threads im Team an diesem Punkt eingehen. Es gibt explizite Barrieren, die durch Direktiven und implizite Barrieren identifiziert werden, die von der Implementierung erstellt wurden.
Konstrukt
Ein Konstrukt ist eine Anweisung. Sie besteht aus einer Direktive, gefolgt von einem strukturierten Block. Einige Direktiven sind nicht Teil eines Konstrukts. (Siehe Openmp-Direktive in Anhang C).
Anweisung
Ein C oder C++
#pragmagefolgt von demompBezeichner, einem anderen Text und einer neuen Zeile. Die Direktive gibt das Programmverhalten an.dynamischer Umfang
Alle Anweisungen im lexikalischen Umfang sowie alle Anweisungen innerhalb einer Funktion, die als Ergebnis der Ausführung von Anweisungen innerhalb des lexikalischen Umfangs ausgeführt wird. Eine dynamische Erweiterung wird auch als Region bezeichnet.
lexikalische Ausdehnung
Anweisungen lexikalisch innerhalb eines strukturierten Blocks gehalten.
Masterthread
Der Thread, der ein Team erstellt, wenn ein paralleler Bereich eingegeben wird.
Parallele Region
Anweisungen, die an ein OpenMP-paralleles Konstrukt binden und von vielen Threads ausgeführt werden können.
privat
Eine private Variable benennt einen Speicherblock, der für den Thread eindeutig ist, der den Verweis erstellt. Es gibt mehrere Möglichkeiten, um anzugeben, dass eine Variable privat ist: eine Definition innerhalb eines parallelen Bereichs, einer Direktive, eines
threadprivateprivate, eines ,firstprivatelastprivateoderreductioneiner Klausel oder der Verwendung der Variablen alsforSchleifensteuerelementvariable in einerforSchleife unmittelbar nach einerforoderparallel foreiner Direktive.Region
Ein dynamisches Ausmaß.
serieller Bereich
Anweisungen, die nur vom Masterthread außerhalb des dynamischen Umfangs eines parallelen Bereichs ausgeführt werden.
serialisieren
So führen Sie ein paralleles Konstrukt mit:
ein Team von Threads, das nur aus einem einzelnen Thread besteht (der Masterthread für dieses parallele Konstrukt)
fortlaufende Ausführungsreihenfolge für die Anweisungen innerhalb des strukturierten Blocks (die gleiche Reihenfolge wie wenn der Block nicht Teil eines parallelen Konstrukts war) und
keine Auswirkung auf den von
omp_in_parallel()(abgesehen von den Effekten geschachtelter paralleler Konstrukte) zurückgegebenen Wert.
freigegeben
Eine freigegebene Variable benennt einen einzelnen Speicherblock. Alle Threads in einem Team, die auf diese Variable zugreifen, greifen auch auf diesen einzelnen Speicherblock zu.
Strukturierter Block
Ein strukturierter Block ist eine Anweisung (single oder compound), die einen einzelnen Eintrag und einen einzelnen Ausgang aufweist. Wenn es einen Sprung in oder aus einer Anweisung gibt, handelt es sich bei dieser Anweisung um einen strukturierten Block. (Diese Regel enthält einen Aufruf an
longjmp(3C) oder die Verwendung vonthrow, obwohl ein Aufrufexitzulässig ist.) Wenn die Ausführung immer beim Öffnen{beginnt und immer am Schließen}endet, ist eine zusammengesetzte Anweisung ein strukturierter Block. Eine Ausdrucksanweisung, Selection-Anweisung, Iterationsanweisung odertryBlock ist ein strukturierter Block, wenn die entsprechende zusammengesetzte Anweisung, die sie durch einschließen{und}ein strukturierter Block ist, abgerufen wird. Eine Jump-Anweisung, eine beschriftete Anweisung oder eine Deklarationsanweisung ist kein strukturierter Block.Mannschaft
Mindestens ein Threads, der bei der Ausführung eines Konstrukts zusammenarbeitet.
Thread
Eine Ausführungsentität mit einem seriellen Kontrollfluss, einer Reihe privater Variablen und Zugriff auf freigegebene Variablen.
-Variable
Ein Bezeichner, optional durch Namespacenamen qualifiziert, der ein Objekt benennt.
1.3 Ausführungsmodell
OpenMP verwendet das Verzweigungsmodell der parallelen Ausführung. Obwohl dieses Fork-Join-Modell nützlich sein kann, um verschiedene Probleme zu lösen, ist es auf große arraybasierte Anwendungen zugeschnitten. OpenMP soll Programme unterstützen, die sowohl als parallele Programme (viele Threads der Ausführung als auch eine vollständige OpenMP-Supportbibliothek) ordnungsgemäß ausgeführt werden. Es ist auch für Programme vorgesehen, die ordnungsgemäß als sequenzielle Programme ausgeführt werden (Direktiven ignoriert und eine einfache OpenMP-Stubsbibliothek). Es ist jedoch möglich und erlaubt, ein Programm zu entwickeln, das sich nicht ordnungsgemäß verhält, wenn es sequenziell ausgeführt wird. Darüber hinaus können unterschiedliche Parallelitätsgrade aufgrund von Änderungen in der Zuordnung numerischer Vorgänge zu unterschiedlichen numerischen Ergebnissen führen. Beispielsweise kann eine seriale Additionsreduktion ein anderes Muster von Additionszuordnungen aufweisen als eine parallele Reduktion. Diese verschiedenen Zuordnungen können die Ergebnisse der Gleitkommazugabe ändern.
Ein Programm, das mit der OpenMP C/C++-API geschrieben wurde, beginnt die Ausführung als einzelner Thread der Ausführung, der als Masterthread bezeichnet wird. Der Masterthread wird in einem seriellen Bereich ausgeführt, bis das erste parallele Konstrukt gefunden wird. In der OpenMP C/C++-API stellt die parallel Direktive ein paralleles Konstrukt dar. Wenn ein paralleles Konstrukt auftritt, erstellt der Masterthread ein Team von Threads, und der Master wird zum Master des Teams. Jeder Thread im Team führt die Anweisungen im dynamischen Umfang einer parallelen Region aus, mit Ausnahme der Arbeitsfreigabekonstrukte. Alle Threads im Team müssen auf Arbeitsfreigabekonstrukte in derselben Reihenfolge treffen, und mindestens ein Thread führt die Anweisungen innerhalb des zugeordneten strukturierten Blocks aus. Die am Ende eines Arbeitsfreigabekonstrukts ohne Klausel nowait implizierte Barriere wird von allen Threads im Team ausgeführt.
Wenn ein Thread ein freigegebenes Objekt ändert, wirkt es sich nicht nur auf seine eigene Ausführungsumgebung, sondern auch auf die der anderen Threads im Programm aus. Die Änderung ist garantiert abgeschlossen, aus Sicht eines anderen Threads am nächsten Sequenzpunkt (wie in der Basissprache definiert), nur wenn das Objekt als veränderlich deklariert wird. Andernfalls wird sichergestellt, dass die Änderung nach dem ändernden Thread abgeschlossen ist. Die anderen Threads sehen dann (oder gleichzeitig) eine flush Direktive, die das Objekt angibt (implizit oder explizit). Wenn die Richtlinien, die flush von anderen OpenMP-Direktiven impliziert werden, nicht die richtige Reihenfolge der Nebenwirkungen garantieren, liegt es in der Verantwortung des Programmierers, zusätzliche, explizite flush Direktiven zu liefern.
Nach Abschluss des parallelen Konstrukts synchronisieren die Threads im Team mit einer impliziten Barriere, und nur der Masterthread setzt die Ausführung fort. Eine beliebige Anzahl paralleler Konstrukte kann in einem einzigen Programm angegeben werden. Daher kann ein Programm während der Ausführung viele Male verzweigen und beitreten.
Die OpenMP C/C++-API ermöglicht Programmierern die Verwendung von Direktiven in Funktionen, die von parallelen Konstrukten aufgerufen werden. Direktiven, die nicht im lexikalischen Umfang eines parallelen Konstrukts erscheinen, aber in dynamischem Umfang liegen können, werden als verwaiste Direktiven bezeichnet. Mit verwaisten Direktiven können Programmierer große Teile ihres Programms parallel ausführen, wobei nur minimale Änderungen am sequenziellen Programm vorgenommen werden. Mit dieser Funktionalität können Sie parallele Konstrukte auf den obersten Ebenen der Programmaufrufstruktur codieren und direktiven verwenden, um die Ausführung in einer der aufgerufenen Funktionen zu steuern.
Nicht synchronisierte Aufrufe von C- und C++-Ausgabefunktionen, die in dieselbe Datei schreiben, können dazu führen, dass Daten, die von verschiedenen Threads geschrieben wurden, in nicht unbestimmter Reihenfolge angezeigt werden. Ebenso können nicht synchronisierte Aufrufe von Eingabefunktionen, die aus derselben Datei gelesen werden, Daten in nicht unbestimmter Reihenfolge lesen. Nicht synchronisierte Verwendung von E/A, sodass jeder Thread auf eine andere Datei zugreift, erzeugt dieselben Ergebnisse wie die serielle Ausführung der E/A-Funktionen.
1.4 Kompatibilität
Eine Implementierung der OpenMP C/C++-API ist OpenMP-kompatibel , wenn sie die Semantik aller Elemente dieser Spezifikation erkennt und bewahrt, wie in Kapitel 1, 2, 3, 4 und Anhang C. Appendices A, B, D, E und F nur zu Informationszwecken und nicht Teil der Spezifikation sind. Implementierungen, die nur eine Teilmenge der API enthalten, sind nicht OpenMP-kompatibel.
Die OpenMP C- und C++-API ist eine Erweiterung der Basissprache, die von einer Implementierung unterstützt wird. Wenn die Basissprache kein Sprachkonstrukt oder eine Erweiterung unterstützt, das in diesem Dokument angezeigt wird, ist die OpenMP-Implementierung nicht erforderlich, um sie zu unterstützen.
Alle Standardmäßigen C- und C++-Bibliotheksfunktionen und integrierte Funktionen (d. h. Funktionen, von denen der Compiler über spezifische Kenntnisse verfügt) müssen threadsicher sein. Die nicht synchronisierte Verwendung threadsicherer Funktionen durch verschiedene Threads innerhalb eines parallelen Bereichs erzeugt kein nicht definiertes Verhalten. Das Verhalten ist jedoch möglicherweise nicht identisch mit einem seriellen Bereich. (Eine Zufallszahlengenerierungsfunktion ist ein Beispiel.)
Die OpenMP C/C++-API gibt an, dass bestimmtes Verhalten implementierungsdefiniert ist . Eine konforme OpenMP-Implementierung ist erforderlich, um das Verhalten in diesen Fällen zu definieren und zu dokumentieren. Eine Liste der implementierungsdefinierten Verhaltensweisen finden Sie in Anhang E.
1.5 Normative Referenzen
ISO/IEC 9899:1999, Informationstechnologie - Programmiersprachen - C. Diese OpenMP-API-Spezifikation bezieht sich auf ISO/IEC 9899:1999 als C99.
ISO/IEC 9899:1990, Informationstechnologie - Programmiersprachen - C. Diese OpenMP-API-Spezifikation bezieht sich auf ISO/IEC 9899:1990 als C90.
ISO/IEC 14882:1998, Informationstechnologie - Programmiersprachen - C++. Diese OpenMP-API-Spezifikation bezieht sich auf ISO/IEC 14882:1998 als C++.
Wenn sich diese OpenMP-API-Spezifikation auf C bezieht, wird auf die Basissprache verwiesen, die von der Implementierung unterstützt wird.