Ist Atomic Read-Modify-Write eine atomare oder trennbare Operation?
Atomare Read-Modify-Write-Operationen (RMW), wie z x.exchange() sind atomare Operationen, die einen Speicherort sowohl lesen als auch schreiben und sicherstellen, dass die Lese- und Schreibvorgänge der Reihe nach ausgeführt werden. Es ist jedoch nicht explizit definiert, ob diese Vorgänge als einzelne atomare Operation oder als Kombination aus Acquire Load und Release Store betrachtet werden.
Die Perspektive des Standards
Aus der Aus Sicht des C-Standards wird eine RMW-Operation als einzelne Operation betrachtet. Dies ist daran zu erkennen, dass es einen einzigen Namen (RMW) hat und im Standard als einzelne Operation bezeichnet wird. In [N4860](https://isocpp.org/files/papers/n4860.pdf) (Draft Working Paper std::memory_order) heißt es beispielsweise:
„Ein Lese-, Änderungs- und Schreibvorgang damit Bei der Speicherreihenfolge handelt es sich sowohl um eine Erfassungsoperation als auch um eine Freigabeoperation. Vorher oder nachher können keine Speicherlese- oder -schreibvorgänge im aktuellen Thread neu angeordnet werden speichern.“
Atomere vs. trennbare Operationen
Die Unterscheidung zwischen atomaren und trennbaren Operationen ist wichtig, da sie bestimmt, wie andere Operationen mit ihnen interagieren. Wenn eine RMW-Operation als atomar behandelt wird, bedeutet dies, dass sie im Hinblick auf andere Speicherzugriffe nicht neu angeordnet werden kann. Wenn es jedoch als trennbar behandelt wird, besteht die Möglichkeit einer Neuordnung zwischen den Lade- und Speicherkomponenten des Vorgangs.
Beispielcode
Betrachten Sie das folgende Codebeispiel , das x.exchange() und y.store() verwendet, um die Werte von zwei atomaren Variablen, x und, festzulegen y.
std::atomic<int> x, y; void thread_A() { x.exchange(1, std::memory_order_acq_rel); y.store(1, std::memory_order_relaxed); } void thread_B() { int yy = y.load(std::memory_order_acquire); int xx = x.load(std::memory_order_acquire); std::cout << xx << ", " << yy << std::endl; }
Wenn x.exchange() als einzelne atomare Operation behandelt wird, bedeutet dies, dass die Lade- und Speicherkomponenten der Operation nicht neu angeordnet werden können. Daher wird Thread B immer beobachten, dass die Werte von x und y beide 1 oder beide 0 sind.
Wenn x.exchange() jedoch als trennbar behandelt wird, bleibt die Möglichkeit offen, dass das Laden und Speichern erfolgt Bestandteile des Betriebs könnten neu angeordnet werden. In diesem Fall könnte Thread B möglicherweise die Werte von x und y als 0, 1 beobachten, da die Last von x vor dem Speichern nach y umgeordnet werden könnte.
Compiler-Implementierung und Standardinterpretation
Aus Sicht des Standards scheint es, dass Thread B 0, 1 nicht beachten sollte. Die ARM64-Implementierung des Codes legt dies jedoch nahe dass der RMW-Vorgang als trennbar behandelt wird, was die Möglichkeit einer Neuordnung zwischen den Lade- und Speicherkomponenten ermöglicht.
Diese scheinbare Diskrepanz wirft die Frage auf, ob das cppreference-Zitat falsch ist oder ob es sich lediglich um ein Missverständnis des Standards handelt. Obwohl es möglich ist, dass das cppreference-Zitat nicht ganz korrekt ist, stimmt es mit der allgemeinen Behandlung von RMW-Operationen durch den Standard als einzelne atomare Operationen überein.
Es ist wichtig zu beachten, dass der Standard das Verhalten von RMW-Operationen nicht explizit definiert alle Umstände. Insbesondere bietet es keine klare Anleitung dazu, wie Synchronisations-mit-Beziehungen auf RMW-Vorgänge angewendet werden. Daher kann Raum für unterschiedliche Interpretationen und Implementierungen von RMW-Operationen bestehen.
Das obige ist der detaillierte Inhalt vonIst atomares Lesen, Ändern und Schreiben eine einzelne oder eine trennbare atomare Operation?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!