Hyper-Threading: Optimierungen und Fallen

SpinCountLoops

Auf einer Single-CPU stellt sich das erwartete Zeitverhalten ein. Die Critical-Section-Schleife dreht 9,8 Millionen Runden pro Sekunde, die Mutex-Lösung lediglich 680 Tausend. Aktiviert man auf dem Testsystem jedoch Hyper-Threading, fallen beide Lösungen auf 250 Tausend ab.

Auf einem Single-CPU-System kann die Critical Section sehr einfach vom Betriebssystem implementiert werden, da hier physikalisch immer nur ein Thread läuft. Arbeiten jedoch mehrere Prozessoren parallel, nutzt das Betriebssystem zur Überwachung der Critical Sections intern auch wieder einen Mutex. Deshalb unterscheiden sich die beiden Fälle in ihrer Geschwindigkeit auch nicht.

Allerdings gibt es eine Möglichkeit, gerade einfache Critical Sections wie im Beispiel auch auf MP-Systemen deutlich zu beschleunigen. Dazu dient der Aufruf SetCriticalSectionSpinCount, der bei Single-CPU-Systemen keine Funktion hat. Deshalb wird er bislang nur von wenigen Entwicklern genutzt. Setzt man den SpinCount nach dem Erzeugen einer Critical Section, so kann man steuern, wie viel Zeit das Betriebssystem bei einer besetzten Critical Section in einer Warteschleife verbringt, bis es den langsamen Mutex bemüht. Wie in den vorgenannten Beispielen wartet das System also ein gewisse Zeit mit Vollgas.

Mit gesetztem SpinCount steigt die Leistung um das 19fache auf 4,7 Millionen an. Dabei ist der Wert des SpinCounts unkritisch, im Bereich von 300 bis 30.000 blieben die Ergebnisse in unserem Fall stabil.

Schleifendurchläufe pro Sekunde

Critical Section

Mutex

Critical Section mit SpinCount

Interlocked Increment

Gemessen mit Pentium 4 3,06 GHz unter Windows XP

Ohne Hyper-Threading

9.765.164

678.163

9.765.164

24.832.365

Mit Hyper-Threading

250.758

247.137

4.741.571

11.765.580