C++ und out-of-order execution
-
Hallo zusammen,
gegenben sei folgendes Code-Snippet:
// MyClass::setValue(int newValue) { // yourMutexType mutex; // boost::mutex, QMutex als Beispiel mutex.lock(); mValue = newValue; mutex.unlock(); }Ist dann das Setzen von mValue dann wirklich in allen Fällen auf einen x86er threadsafe ?
Prinzipiell darf der Compiler doch die Write-Back Reihenfolge umsortieren (siehe Topic).Bitte keine sinnlosen Diskussionen über volatile starten.
Ich gehe übrigens davon aus, dass mutex keinen impliziten Memory Barrier hat und CPU Architektur ist x86 (cache-cohärent).
-
Angenommen, es waere nicht threadsafe, welchen Sinn macht dann
mutexbzw. deine verwendete Bibliothek?
-
In der abstrakten Maschine erfolgt die Zuweisung nach dem Lock und vor dem Unlock (schon allein deshalb, weil das Semikolon jeweils einen Sequenzpunkt darstellt).
Der Compiler darf Reihenfolgen verändern, sofern das die Semantik des Programmes nicht verändert (aus Sicht eines einzelnen Threads). Das wäre also nur dann möglich, wenn weder Lock noch Unlock eine Abhängigkeit bzgl. mValue haben. Dieses Fehlen der Abhängkeit kann der Compiler im Prinzip nur dann beweisen, wenn er den Code dieser Funktionen kennt. Jede brauchbare Threading-Bibliothek ist allerdings so geschrieben, dass genau das nicht der Fall ist, die Funktionen also opaque sind. Ist auf diese Weise eine Umordnung durch den Compiler ausgeschlossen, genügt die Bedingung von sequentieller Cache-Kohärenz auch ohne explizite Barriers, sofern jeder Zugriff auf mValue von entsprechenden Locks umgeben ist.
-
Okay, die Antwort geht in die Richtung die ich wissen wollte.
Allerdings sollte in meiner threading-bibliothek doch explizit das Opaque-Verhalten in der Doku erwähnt sein, oder nicht ?
Bei QT finde ich in der Doku von QMutex beispielsweise nichts darüber, aber beim QAtomicInt kann ich mir die Art der Memory Order auswählen.
-
Also ich glaube, so etwas Gravierendes wäre bereits aufgefallen...