5

Wenn ich eine gemeinsame Variable verwende, sagen wir ein Double, um eine Art Summe während der Ausführung des Programms zu berechnen. Wäre das für instabile Operationen anfällig? Ich meine, wäre es möglich, dass mehr als ein Kern asynchron auf diese Variable zugreifen und zu instabilen Ergebnissen führen würde?C++: OpenMP shared memory protection

Zum Beispiel: dies ist eine globale Variable:

double totalTime = 0; 

und in jedem Kern ein Befehl aufgerufen wird:

totalTime += elapsedTime; 

Diese letzte Operation/Anweisung wird berechnet, indem der Wert von totaltime ausgeführt Setzen Sie es in das CPU-Register und führen Sie dann die Addition durch. Ich kann mir vorstellen, dass mehr als ein Kern im selben Augenblick den gleichen Wert annimmt und dann die neue elapsedTime hinzufügt, und dann würde der in totalTime gespeicherte Wert aufgrund der Latenz mit dem falschen Wert überschrieben werden. Ist das möglich? und wie kann ich das lösen?

Vielen Dank.

Antwort

4

Offensichtlich ist diese Operation nicht Thread-sicher, da, wie Sie selbst erwähnt haben, es mehrere Assembler-Anweisungen beinhaltet. In der Tat hat openMP sogar eine spezielle Richtlinie für diese Art von Operationen.

Sie müssen die atomic Pragma zu machen, na ja, „atomar“:

#pragma omp atomic 
totalTime += elapsedTime; 

Beachten Sie, dass atomic funktioniert nur, wenn Sie ein einzelnes Update auf einen Speicherplatz haben, wie ein Zusatz, erhöhe usw. .

Wenn Sie eine Reihe von Anweisungen, die Sie zusammen zu Atom benötigen müssen die critical Direktive verwenden:

#pragma omp critical 
{ 
    // atomic sequence of instructions 
} 

bearbeiten: Hier ist ein guter Vorschlag von „snemarch“: Wenn Sie wiederholt die globale Variable totalTime in einer parallelen Schleife zu aktualisieren sind, können Sie die reduction Klausel betrachten den Prozess zu automatisieren und es auch viel effizienter machen:

double totalTime = 0; 

#pragma omp parallel for reduction(+:totalTime) 
for(...) 
{ 
    ... 
    totalTime += elapsedTime; 
} 

Am Ende enthält totalTime korrekt die Summe der lokalen Werte elapsedTime ohne explizite Synchronisation.

+0

Danke, Kumpel :) –

+0

Ich frage mich, wie OpenMP atomare fügt für Fließkomma-Datentypen auf x86 unterstützt - es gibt keine native Anweisung dafür. Kritische Abschnitte? – snemarch

+0

@snemarch: Ich konnte nichts definitives finden, also denke ich, dass es Sperren verwendet. – Tudor