Die meisten Prozessoren unterstützen ein atomares Lesen oder Schreiben und häufig ein atomares cmp & swap. Dies bedeutet, dass der Prozessor selbst den neuesten Wert in einer einzelnen Operation schreibt oder liest und im Vergleich zu einem normalen Ganzzahlzugriff möglicherweise einige Zyklen verloren gehen, zumal der Compiler nicht annähernd so gut wie normal für atomare Operationen optimieren kann.
Auf der anderen Seite ist ein Mutex eine Anzahl von Codezeilen, die eingegeben und verlassen werden müssen, und während dieser Ausführung sind andere Prozessoren, die auf denselben Speicherort zugreifen, vollständig blockiert, was eindeutig einen großen Aufwand für sie bedeutet. In nicht optimiertem High-Level-Code sind der Mutex-Ein- / Ausgang und der Atom-Funktionsaufruf. Bei Mutex wird jedoch jeder konkurrierende Prozessor gesperrt, während Ihre Mutex-Eingabefunktion zurückkehrt und Ihre Exit-Funktion gestartet wird. Für Atomic ist nur die Dauer der eigentlichen Operation gesperrt. Durch die Optimierung sollten diese Kosten gesenkt werden, jedoch nicht alle.
Wenn Sie versuchen, ein Inkrement zu erstellen, unterstützt Ihr moderner Prozessor wahrscheinlich das atomare Inkrementieren / Dekrementieren, was großartig sein wird.
Ist dies nicht der Fall, wird es entweder mit dem Prozessor Atomic Cmp & Swap oder mit einem Mutex implementiert.
Mutex:
get the lock
read
increment
write
release the lock
Atomic cmp & Swap:
atomic read the value
calc the increment
do{
atomic cmpswap value, increment
recalc the increment
}while the cmp&swap did not see the expected value
Diese zweite Version hat also eine Schleife [falls ein anderer Prozessor den Wert zwischen unseren atomaren Operationen erhöht, sodass der Wert nicht mehr übereinstimmt und das Inkrement falsch wäre], die lang werden kann [wenn es viele Konkurrenten gibt], aber im Allgemeinen immer noch schneller sein sollte als die Mutex-Version, aber die Mutex-Version kann es diesem Prozessor ermöglichen, die Task zu wechseln.