2.6.4 atomic-Konstrukt
Die atomic-Direktive sicherzustellen, dass einer bestimmten Speicheradresse atomar aktualisiert wird, anstatt sie an die Möglichkeit mehrerer Threads erfolgt, gleichzeitigen Schreibvorgänge verfügbar. Die Syntax der atomic-Direktive sieht wie folgt aus:
#pragma omp atomic new-line
expression-stmt
Die Ausdrucksanweisung muss eines der folgenden Formate haben:
binop= x expr
x++
++x
x--
--x
In den vorangehenden Ausdrücke:
x ist ein lvalue Ausdruck mit skalarem Typ.
expr ist ein Ausdruck mit skalarem Typ und verweist nicht auf das Objekt, das von xfestgelegt ist .
binop Ist kein überladener Operator und ist ein von +, -, *,/, &^, |<<, oder >>.
Obwohl sie Implementierung-definiert wird, ob eine Implementierung alle atomic-Direktive durch Kritisch-Direktive ersetzt, die denselben eindeutigen Namenverfügen, ermöglichen die atomic-Direktive bessere Optimierung. Häufig sind die Anweisungen verfügbar, dass das atomare Aktualisierungen mit dem wenig Mehraufwand führen kann.
Nur die Auslastung und der Speicherung des Objekts, das von x festgelegt ist, sind atomar. die Auswertung von expr ist keine atomar. Um Racebedingungen zu vermeiden, sollten alle Aktualisierungen des Speicherorts mit den atomic-Direktive geschützt werden parallel mit Ausnahme der von Racebedingungen die freigegeben werden soll.
Einschränkungen für atomic-Direktive lauten wie folgt:
- Alle atomaren Verweise auf den Speicherort x während des Programms sind erforderlich, um einen kompatiblen Typ aufweisen.
Beispiele:
extern float a[], *p = a, b;
/* Protect against races among multiple updates. */
#pragma omp atomic
a[index[i]] += b;
/* Protect against races with updates through a. */
#pragma omp atomic
p[i] -= 1.0f;
extern union {int n; float x;} u;
/* ERROR - References through incompatible types. */
#pragma omp atomic
u.n++;
#pragma omp atomic
u.x -= 1.0f;