Hyper-Threading: Optimierungen und Fallen

Dummer Code?

Nach gängiger Meinung sollte so etwas nicht passieren können, da der Inkrement eines Integers mit einem einzigen Inc-Befehl erfolgen soll. Deshalb könne er nicht unterbrochen werden und sei demnach Thread-sicher.

Doch ein Blick in den vom Microsoft-Compiler ohne spezielle Optimierungen erzeugten Code zeigt schnell die erste Stolperfalle. Der Compiler nutzt nicht einen einzelnen Inc-Befehl, sondern lädt die Variable in ein Register, addiert im nächsten Befehl eine 1 und schreibt dann das Ergebnis wieder zurück.

Wird diese Befehlsfolge in der Mitte vom Scheduler unterbrochen und verändert ein anderer Thread zwischenzeitlich die Variable, geht die Addition schief. Das Gleiche gilt, wenn auf einer Hyper-Threading-CPU zwei Threads gleichzeitig in diesem Code-Abschnitt arbeiten. Dies trifft bei dem gezeigten Assembler-Code auch für Single-CPU-Systeme zu. Allerdings ist dabei die Wahrscheinlichkeit für einen Fehler nicht sonderlich hoch, da bei einer einzelnen CPU nur einige zig Thread-Wechsel pro Sekunde auftreten.