Sind +=, |=, &= usw. atomar? [duplicate]

Lesezeit: 4 Minuten

Sind die “Ändern”-Operatoren wie +=, |=, &= etc atomar?

Ich weiss ++ ist atomar (wenn Sie durchführen x++; in zwei verschiedenen threads “gleichzeitig” landest du immer mit x um 2 erhöht, im Gegensatz zu x=x+1 bei ausgeschalteter Optimierung.)

Was ich mich frage ist, ob variable |= constantund die Likes sind Thread-sicher oder muss ich sie mit einem Mutex schützen?

(…oder ist es CPU-abhängig? Wie ist es in diesem Fall auf ARM?)

  • Welcher ARM? Architektur v6 (ARM10) und höher kann atomare Operationen bereitstellen, wenn der Compiler dies unterstützt oder Sie Ihre eigene Assembly rollen. Frühere Architekturen können das nicht.

    – Mike Seymour

    18. März 2010 um 11:20 Uhr

  • gcc hat eingebaute atomare Operationen: gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/… ; Bitte beachten: “Nicht alle Operationen werden von allen Zielprozessoren unterstützt”

    – Christoph

    18. März 2010 um 11:41 Uhr


  • Es gibt eine Windows-API für den Zugriff auf verriegelte Variablen: msdn.microsoft.com/en-us/library/ms684122%28v=VS.85%29.aspx

    – Janusz Lenar

    18. März 2010 um 12:31 Uhr


  • Abgesehen davon, dass die Sprache dies nicht garantiert, hat x86-64 einen starken Speichermodus (lädt erwerben und speichert freigeben), und selbst dort, z INC m64 da eine RMW-Operation nicht garantiert atomar ist, es sei denn, die LOCK Präfix verwendet.

    – Arne Vogel

    16. November 2018 um 13:43 Uhr

Sie liegen falsch. Es gibt keine Garantie dafür, dass ++ atomar ist, und es gibt auch keine Garantie für zusammengesetzte Zuweisungsoperatoren oder überhaupt für C++-Operationen.

  • Das heißt, das ist CPU-spezifisch. Auf Single-Core-Architekturen, die es zulassen inc [address]das ist definitiv atomar.

    – SF.

    18. März 2010 um 10:15 Uhr


  • Zumindest nicht bis C++0x: “Diese Klausel beschreibt Komponenten für feinkörnigen atomaren Zugriff. Dieser Zugriff wird über Operationen auf atomaren Objekten bereitgestellt.” [29.1/1 in the n3035 draft].

    Roger Pate

    18. März 2010 um 10:15 Uhr

  • @SF Nein ist es nicht. Es ist Compiler-spezifisch. Nur weil eine CPU-Architektur eine Anweisung hat, bedeutet das nicht, dass der Compiler sie so verwendet, wie Sie es sich vorstellen, wenn er sie überhaupt verwendet.

    anon

    18. März 2010 um 10:16 Uhr

  • Selbst wenn der Compiler ein atomares Inkrement erzeugen kann, kann es vom Datentyp von x abhängen, ob x++ atomar sein kann. Zum Beispiel ist auf dem Ziel von SF ein Inkrement von x, wenn x „long long“ ist, nicht atomar, und wenn es ein anderer integraler Typ wäre, könnte es möglicherweise von der spezifischen ARM-Architektur und der Datenausrichtung abhängen.

    – Clifford

    18. März 2010 um 12:45 Uhr

  • @SF: Das ist sehr spezifisch. Was ist, wenn der Compiler diese Anweisung nicht verwendet? Was ist, wenn/wenn Sie auf ein Multicore-System upgraden? Was ist mit Architekturen, die die nicht haben inc Anweisung? Im Algemeinen, ++ ist nicht atomar. Sie haben gerade einen einzigen engen Sonderfall gefunden, bei dem dies kein Problem darstellt

    – jalf

    18. März 2010 um 13:42 Uhr

x++ wird oft in 3 Anweisungen implementiert: Lies X in ein Register, inkrementiere es und schreibe es zurück in den Speicher.

Ihr Thread kann zwischen diesen vorbelegt werden.

  • Bei einigen Prozessoren können sogar einzelne Befehle nicht-atomar sein.

    – Jive Dadson

    19. August 2012 um 2:54 Uhr

Damit die Wertänderung über Kerne hinweg sichtbar ist, müsste ein += (zum Beispiel) den Wert laden, das Inkrement hinzufügen und dann speichern. Das bedeutet, dass die Operation ist nicht atomar.

Um die Atomarität sicherzustellen, müssten Sie die Operation entsprechend sperren.

Nein, sie sind nicht atomar! Wenn Sie atomare Operationen für primitive Typen benötigen und Linux verwenden, können Sie hier nachsehen: http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html und/oder atomar.h…

++ kann auf Ihrem Compiler/Ihrer Plattform atomar sein, aber in den C++-Spezifikationen ist es nicht als atomar definiert.

Wenn Sie sicherstellen möchten, dass ein Wert atomar geändert wird, sollten Sie die entsprechenden Methoden verwenden, z. B. Interlocked* unter Windows.

Gleiches gilt für alle anderen Routinen. Wenn Sie atomare Operationen wünschen, sollten Sie die entsprechenden Aufrufe verwenden, nicht die Standardaufrufe.

Benutzer-Avatar
Sockel

Nein Operator in C oder C++ ist garantiert atomar. Sie könnten auf Ihrer Plattform sein, aber Sie werden es nicht sicher wissen. Typischerweise ist die einzige Operation, die atomar ist, die Anweisung Test and Set, die normalerweise auf den meisten modernen CPUs in irgendeiner Form als Grundlage für die Implementierung von Semaphoren verfügbar ist.

Benutzer-Avatar
JoeG

Es ist sowohl Compiler- als auch CPU-abhängig. Einige Befehlssätze bieten atomare Anweisungen für diese (auf Ints in Maschinengröße).

Es gibt jedoch keine Garantie dafür, dass Ihr Compiler diese Anweisungen verwendet und Ihren Code nicht auf nicht-threadsichere Weise optimiert. Sie müssen entweder eine Routine in Assembly schreiben oder eine Compiler-spezifische Technik (z. B. intrinsics) verwenden, die Atomarität bietet (oder eine Bibliothek verwenden, die eine dieser Techniken verwendet).


Speziell bei ARM: Die ORR/ADD/AND-Anweisungen nehmen zwei Operanden und platzieren das Ergebnis in einem Register. Jeder Operand kann dasselbe Register wie das Ergebnisregister sein, sodass sie als atomares |=, +=, &= verwendet werden können.

Natürlich wird das Ergebnis in ein Register geschrieben und der erste Operand muss auch aus einem Register stammen, also müssen Sie sicherstellen, dass die Registerladevorgänge atomar erfolgen.

1383920cookie-checkSind +=, |=, &= usw. atomar? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy