Unter einem x86-Prozessor bin ich mir nicht sicher über den Unterschied zwischen atomaren Operationen zum Vergleichen und Tauschen und Laden / Laden bedingter Operationen. Ist letzteres sicherer als das erstere? Ist der erste besser als der zweite?
Es gibt drei gängige Stile für atomare Primitive: Vergleichen - Exchange, Load-Linked / Store-Conditional und Compare-and-Swap.
Eine CompareExchange-Operation liest automatisch einen Speicherort und speichert einen angegebenen neuen Wert, wenn dieser mit einem Vergleichswert übereinstimmt. Wenn der gelesene Wert nicht mit dem Vergleichswert übereinstimmt, findet kein Speichern statt. In jedem Fall meldet die Operation den gelesenen Originalwert.
Eine Compare-And-Swap-Operation ähnelt CompareExchange, außer dass sie nicht meldet, welcher Wert gelesen wurde - lediglich ob der Wert, der gelesen wurde, mit dem Vergleichswert übereinstimmt. Beachten Sie, dass CompareExchange verwendet werden kann, um Compare-and-Swap zu implementieren, indem es meldet, ob der aus dem Speicher gelesene Wert mit dem angegebenen Vergleichswert übereinstimmt.
Die LL / SC-Kombination ermöglicht, dass ein Speichervorgang davon abhängig gemacht wird, ob ein Einfluss von außen das Ziel beeinflusst hat, seit dessen Wert geladen wurde. Insbesondere garantiert es, dass der Standort, wenn der Speicher erfolgreich ist, überhaupt nicht von externem Code geschrieben wurde. Selbst wenn externer Code einen neuen Wert schreibt und dann den ursprünglichen Wert neu schreibt, würde dies garantiert dazu führen, dass der bedingte Code fehlschlägt. Konzeptionell könnte dies dazu führen, dass LL / SC leistungsfähiger erscheint als andere Methoden, da es nicht das "ABA" -Problem hätte. Unglücklicherweise erlauben LL / SC-Semantiken, dass Speicher spontan ausfallen, und die Wahrscheinlichkeit eines spontanen Fehlers kann schnell steigen, wenn die Komplexität des Codes zwischen der Last und dem Speicher erhöht wird. Die Verwendung von LL / SC, um etwas wie ein atomares Inkrement direkt zu implementieren, wäre effizienter als die Verwendung eines Compare-and-Swap und dann die Implementierung eines atomaren Inkrements unter Verwendung dieser Compare-and-Swap-Implementierung in Situationen, in denen eine benötigt würde Um viel zwischen einem Laden und Speichern zu tun, sollte LL-SC im Allgemeinen verwendet werden, um ein Compare-and-Swap zu implementieren, und dann diese Compare-and-Swap-Methode in einer load-modify-CompareAndSwap-Schleife verwenden.
Von den drei Primitiven ist der Compare-and-Swap der am wenigsten mächtige, aber er kann in Bezug auf die beiden anderen implementiert werden. CompareAndSwap kann CompareExchange sehr gut emulieren, obwohl es in einigen Fällen Fälle gibt, in denen eine solche Emulation live-lock sein könnte. Weder CompareExchange noch Compare-And-Swap können Garantien bieten, die so stark wie LL-SC sind, obwohl die begrenzte Menge an Code, die man zuverlässig in einem LL / SC-Loop platzieren kann, den Nutzen seiner Garantien einschränkt.
Tags und Links c++ atomic compare-and-swap