Hyper-Threading: Optimierungen und Fallen

Schneller durch Sleep?

Auf einer Single-CPU ist der bisherige Ansatz unbrauchbar, da hier die meiste Zeit mit sinnlosem Warten in einer Schleife verbraucht wird. Für solche Fälle bietet sich der Einsatz der Sleep()-Funktion an. Mit dieser Kernel-Funktion kann ein Thread dem Scheduler mitteilen, dass er gerade nichts zu tun hat. Daraufhin entzieht ihm der Scheduler die CPU und vergibt die nächste Zeitscheibe neu.

Im Beispiel ist jetzt die leere Warteschleife lediglich mit Sleep(0) gefüllt. In einer Single-CPU-Maschine ändert sich nun das Verhalten drastisch. Statt elf Wechseln pro Sekunde agieren die beiden Threads nun 1,3 Millionen Mal pro Sekunde.

Mit Hyper-Threading ist dies jedoch nicht der Weisheit letzter Schluss. Denn der Aufruf von Sleep() ist relativ aufwendig. Der Scheduler des Betriebssystems wird dabei aktiv und geht durch seine Listen der wartenden Threads. Anschließend belegt er die nächste Zeitscheibe neu. Auf einer Hyper-Threading-CPU mit zwei aktiven Threads kommt dabei jedoch meist derselbe Thread wieder zum Zuge, so dass der Scheduler-Aufruf sinnlos Rechenleistung verbraucht. Im obigen Beispiel sinkt daher die Leistung von 8,6 Millionen Loops pro Sekunde auf 2,4 Millionen.