Ich verwende OpenMP und muss die Funktion fetch-and-add verwenden. OpenMP stellt jedoch keine entsprechende Anweisung/Aufruf bereit. Ich möchte die maximale Portabilität beibehalten, daher möchte ich mich nicht auf Compiler-Intrinsics verlassen.Abrufen und Hinzufügen mithilfe von atomaren OpenMP-Vorgängen
Ich bin eher auf der Suche nach einer Möglichkeit, die atomaren Operationen von OpenMP zu nutzen, um dies zu implementieren, aber ich habe eine Sackgasse erreicht. Kann das überhaupt gemacht werden? N. B., der folgende Code fast tut, was ich will:
#pragma omp atomic
x += a
Fast - aber nicht ganz, da ich wirklich den alten Wert von x
benötigen. fetch_and_add
sollte produzieren definiert werden, um das gleiche Ergebnis wie die folgende (nur nicht-locking): konnte
template <typename T>
T fetch_and_add(volatile T& value, T increment) {
T old;
#pragma omp critical
{
old = value;
value += increment;
}
return old;
}
(Eine äquivalente Frage für Vergleichs- und Auslagerungs gefragt, aber man kann in Bezug auf die anderen umgesetzt werden, wenn ich mich nicht irre)
genau das zu sagen, "atomar" ist nicht wirklich, was sein Name zu versprechen scheint, da jeder Thread, dessen Speicher durch einen "atomaren" (auf irgendeinem anderen Thread) geändert wurde, erneut cachen muss. So häufige und wiederholte "atomare" können Ihre Leistung töten (besser Sperren verwenden und Puffer schreiben schreibt). – Walter
@Walter Das ist auch, was ich empirisch gefunden habe: Lock-Free-Algorithmus, der nur auf Augenhöhe mit dem äquivalenten Algorithmus funktioniert, der Sperren verwendet. Und der Lock-Free-Algorithmus verwendet eine weitaus komplexere Synchronisation - nicht in Bezug auf die Leistung, sondern in Bezug auf die Logik (und somit die Möglichkeiten, Fehler einzuführen). –