2016-08-11 2 views
5

Vom documentation:Does MS-spezifischer flüchtige verhindern Hardware Anweisungen Neuordnungs

Microsoft Specific

Wenn die/volatilen: ms-Compiler-Option wird verwendet-standardmäßig, wenn andere Architekturen ARM sind targeted - der Compiler generiert zusätzlichen Code, um die Reihenfolge unter Verweisen auf flüchtige Objekte in zusätzlich zur Aufrechterhaltung der Reihenfolge zu Referenzen auf andere globale Objekte zu pflegen.Insbesondere:

  • Ein Schreiben in ein flüchtiges Objekt (auch als flüchtiges Schreiben bekannt) hat Semantik zum Freigeben; Das heißt, ein Verweis auf ein globales oder statisches Objekt
    , das auftritt, bevor ein Schreibvorgang in ein flüchtiges Objekt in der Anweisung Sequenz vor dem flüchtigen Schreibvorgang in der kompilierten
    Binärdatei erfolgt.
  • Ein Lesevorgang eines flüchtigen Objekts (auch bekannt als flüchtiger Lesevorgang) hat die Semantik Acquire; das heißt, eine Referenz auf ein globales oder statisches Objekt
    , das auftritt, nachdem ein Lesen des flüchtigen Speichers in der Anweisung
    Sequenz nach dem flüchtigen Lesen in der kompilierten Binärdatei erfolgt.
  • Dadurch können flüchtige Objekte für Speichersperren und Freigaben in Multithread-Anwendungen verwendet werden.

    Es garantiert sicher, dass volatile Compiler verhindert Kompilierung-Anweisungen tun Neuordnen (weil es ausdrücklich, dass die Anweisung Sequenz wird die gleiche in der kompilierten binären sein).

    Aber wie wir alle wissen, gibt es auch so etwas wie Hardware-Neuordnung (wie CPU in der Lage, Anweisungen auf eigene Faust neu zu ordnen). Verhindert das volatile es auch? Ich weiß, dass Synchronisationsgrundelemente (wie Mutexe) tun, aber was ist mit MS-spezifischen volatile?

    +1

    Mit "anderen Architekturen als ARM" bedeutet MS wahrscheinlich x86 und x64. Auf x86 und x64 werden Lasten nicht mit anderen Lasten neu angeordnet. Und Geschäfte werden nicht mit anderen Geschäften bestellt. (mit einigen Ausnahmen wie nicht-temporären Speichern) IOW, solange der Compiler nichts neu anordnet, auch der Prozessor nicht. Es scheint, dass '/ volatile' für MS versucht, die Funktionalität von' std :: atomic' bereitzustellen, die bis C++ 11 nicht existierte. – Mysticial

    +0

    Außerdem sagen sie "hat Release-Semantik", so dass die Dokumentation mit Sicherheit behauptet * 'volatile' verhindert CPU-Neuordnung. –

    +0

    @Mysticial "Es scheint, dass/volatile für MS versucht, die Funktionalität von std :: atomic bereitzustellen" - nein, tut es nicht. Zum Beispiel ist nicht garantiert, dass Lese- und Schreiboperationen für "flüchtige" Variablen atomar sind. In der Tat sind sie - weil x86 Atomizität von Lese-und Schreiboperationen für 1-Byte-Variablen garantiert, aber es ist nicht in MSDN von "volatile" garantiert – FrozenHeart

    Antwort

    7

    Die MSDN-Dokumentation zu dem MS-spezifischen volatilen Verhalten reicht bis zu VS2003 zurück. Es ist also schon eine ganze Weile her - vor der Existenz von std::atomic in C++ 11.

    So MS-spezifische volatile scheint die Art und Weise zu sein, die man erreicht, Semantik in den alten Tagen zu erwerben/freizugeben. Aber jetzt ist es im Grunde obsolet und sie haben eine Fußnote hinterlassen, die Sie von MS-volatile zu Gunsten std::atomic und /volatile:iso für Inter-Thread-Kommunikation wegstoßen.

    Warum sie ARM ausschließen, Microsoft hat ARM erst vor relativ kurzer Zeit abholen. Anders als ARM unterstützen sie x86, x64 und Itanium (was tot ist).

    Auf x86 und x64 haben die meisten Lade- und Speichervorgänge bereits eine Semantik zum Erfassen/Freigeben (mit Ausnahmen wie nicht temporären Speichern). Solange der Compiler nichts neu anordnet, wird der Prozessor weder * noch die Semantik Erwerb/Freigabe beibehalten.Das /volatile:ms Flag weist den Compiler an, nichts neu zu ordnen, damit die Semantik zum Akquirieren/Freigeben auf x86 und x64 erreicht werden kann.

    Da Microsofts ARM-Unterstützung ist relativ neu, und MS-spezifische volatile (/volatile:ms) zugunsten std::atomic veraltet ist, entschieden sie sich wahrscheinlich die klassische flüchtige Semantik anstatt zu aktualisieren, sie zu verlassen als auch auf ARM arbeiten (was würde wahrscheinlich bedeutet, Speicherbarrieren überall hinzuzufügen, da es an Hardware fehlt.

    * Der Prozessor wird immer noch tun, was auch immer er nachbestellen will, aber es wird die Erwerb/Release-Semantik des Programms beibehalten, da dies von x86/x64 benötigt wird. (abzüglich der Ausnahmefälle wie nt-stores oder clflush) Wie dies geschieht, ohne die Speicherordnung zu verletzen, ist ein anderes Thema.