In diesem Video zu Disruptor , ein Concurrency-Framework, wird die lazySet-Methode der Java-Atomic * -Klassen (zB AtomicLong) erwähnt. Laut der Dokumentation , diese Methode "setzt schließlich auf den gegebenen Wert".
Weiß jemand, was der zugrunde liegende Mechanismus ist, um dies zu implementieren (speziell auf x86 unter Windows, wenn das relevant ist)? Es kann nicht InterlockedExchange () sein, da dies den Wert festlegen und Cache-Zeilen sicherstellen würde werden vor der Rückkehr gespült, wenn ich mich nicht irre.
Diese Beschreibung der Implementierung wurde in Fehler 6275329 gefunden:
Die Semantik besagt, dass der Schreibvorgang garantiert nicht mit einem anderen Befehl neu geordnet wird vorheriges Schreiben, kann jedoch mit nachfolgenden Operationen neu geordnet werden (oder äquivalent, möglicherweise nicht für andere Threads sichtbar) bis eine andere flüchtige Schreib- oder Synchronisierungsaktion findet statt).
...
Für Leute, die gerne an diese Operationen denken Barrieren auf Maschinenebene auf gemeinsamen Multiprozessoren bietet lazySet a vorhergehende Store-Store-Barriere (das ist entweder ein No-Op oder sehr billig auf aktuellen Plattformen), aber keine Ladenladeschranke (was normalerweise der Fall ist) teurer Teil eines flüchtigen Schreibens)
Dies ruft im Grunde unsafe.putOrderedLong()
auf, was eine native Funktion ist. Auf der Grundlage der Unterscheidung in unsicheren zwischen gemacht bestellt (faul) vs volatile (sofort). Ich bin fast sicher, dass die (faul) Version einfach auf ein storestore
löst, während flüchtige das teurere loadstore
erfordert. Dies bewahrt die Threading-Semantik (für den Einstellungs-Thread), ohne alle anderen Kerne anzuhalten. Schließlich werden die Leser den neuen Wert abholen.
[Edit: Das heißt (die spekulativ ist), ich bin sicher , dass die faulen Speicher verwendet ‚leichter‘ Speicher Umzäunung, die durch die volle flüchtigen verwendet - wenn die Plattform die es bietet. Z.B. Ich sehe nicht, was man nicht in C # machen kann, sagen wir für x86]
Die typische Verwendung von etwas wie diesem ist ein Zähler (z. B. Warteschlangentiefe). Wenn Sie ein flüchtiges bei jeder Iteration getroffen, wird es nicht „High Performance“, wie Sie die vollen Kosten für die Cache-Kohärenz in jeder Iteration entstehen. Wenn Ihre gleichzeitige ‚fuzzy‘ Ablesungen Interaktion erlaubt dann (die Interaktion über die Speicher) dann diese Technik reduziert die Kosten der maintaing Gesamtsystemzustand (in einem akzeptablen Fehlerbereich z.B. beim Lesen von Warteschlangentiefe ist ein wenig aus.)
[ps / edit:. Diskussion von Zäunen von Distruptor-Designer ]
Tags und Links java concurrency