Wie wir aus C11-memory_order wissen: Ссылка
Und das gleiche aus C ++ 11-std :: memory_order: Ссылка
Auf stark geordneten Systemen ( x86 , SPARC, IBM Mainframe), release-act-Bestellung ist automatisch. Keine zusätzlichen CPU-Anweisungen werden für diesen Synchronisationsmodus ausgegeben , nur bestimmte Compiler Optimierungen sind betroffen (z. B. der Compiler ist verboten von nicht-atomare Speicher nach dem Atomspeicher-Release verschieben oder durchführen nichtatomare Lasten früher als die atomare Ladungserfassung)
Aber gilt das für x86-SSE-Anweisungen (außer [NT] - nicht-temporal, wo wir immer L / S / MFENCE verwenden müssen)?
Hier gesagt, dass " sse Anweisungen ... ist keine Voraussetzung für die Abwärtskompatibilität und die Speicherreihenfolge ist nicht definiert ". Es wird angenommen, dass die strenge Bestellbarkeit für die Kompatibilität mit älteren Versionen von Prozessoren x86, wenn es nötig war, aber neue Befehle, nämlich SSE (mit Ausnahme von [NT]) - beraubt automatisch Release-Erwerb der Ordnung, ist es?
Hier ist ein Auszug aus Intel Software Developers Manual, Band 3 , Abschnitt 8.2.2 (die Ausgabe 325384-052US vom September 2014):
- Lesevorgänge werden nicht mit anderen Lesevorgängen neu geordnet.
- Schreibvorgänge werden nicht mit älteren Lesevorgängen neu geordnet.
- Schreibvorgänge in den Speicher werden nicht mit anderen Schreibvorgängen neu angeordnet, mit folgenden Ausnahmen:
- schreibt mit der CLFLUSH-Anweisung ausgeführt;
- Streaming-Speicher (Schreibvorgänge), die mit den nicht-temporalen Bewegungsinstruktionen (MOVNTI, MOVNTQ, MOVNTDQ, MOVNTPS und MOVNTPD) ausgeführt werden; und
- String-Operationen (siehe Abschnitt 8.2.4.1).
- Lesevorgänge können mit älteren Schreibvorgängen an verschiedenen Speicherorten neu angeordnet werden, jedoch nicht mit älteren Schreibvorgängen am selben Speicherort.
- Lese- oder Schreibvorgänge können nicht mit E / A-Anweisungen, gesperrten Anweisungen oder Serialisierungsanweisungen neu geordnet werden.
- Lesevorgänge können frühere LFENCE- und MFENCE-Anweisungen nicht bestehen.
- Writes können frühere LFENCE-, SFENCE- und MFENCE-Anweisungen nicht weitergeben.
- LFENCE-Befehle können frühere Lesevorgänge nicht bestehen.
- SFENCE-Anweisungen können keine früheren Schreibvorgänge passieren.
- MFENCE-Befehle können keine früheren Lese- oder Schreibvorgänge bestehen.
Die ersten drei Aufzählungszeichen beschreiben die release-act-Reihenfolge, und die Ausnahmen sind dort explizit aufgeführt. Wie Sie vielleicht sehen, befinden sich nur Cachability-Steuerbefehle ( MOVNT*
) in der Ausnahmeliste, während der Rest von SSE / SSE2 und anderen Vektorbefehlen den allgemeinen Speicherordnungsregeln folgt und keine Verwendung von [LSM]FENCE
.
Es ist richtig, dass normale 1 SSE-Lade- und Speicherbefehle sowie die implizierte Last bei Verwendung eines Speicherquellenoperanden die gleiche -Akquise und -Freigabe haben Verhalten in Bezug auf Ordnen als normale Lasten und Speichern von GP-Registern.
Sie sind nicht , sind jedoch im Allgemeinen nützlich, um std::memory_order_acquire
oder std::memory_order_release
-Operationen für std::atomic
-Objekte größer als 8 Byte zu implementieren, da keine Garantie für Atomizität für SSE oder AVX lädt und speichert von mehr als 8 Bytes. Die fehlende Garantie ist nicht nur theoretisch: Es gibt mehrere Implementierungen (einschließlich brandneuer wie AMDs Ryzen), die große Lasten aufteilen oder in zwei kleinere aufteilen.
1 Das heißt, diejenigen, die nicht in der Ausnahmeliste in der akzeptierten Antwort aufgeführt sind: NT speichert, clflush
und Zeichenfolgenoperationen.
Tags und Links x86 c++11 sse memory-barriers c11