Hyper-Threading-Benchmarks

Fallstricke beim Programmieren

Um von Hyper-Threading zu profitieren, muss eine Applikation multithreaded programmiert sein. Ein häufiges Problem dabei stellt die Synchronisation einzelner Threads dar. Im einfachsten Fall geschieht dies über ein gemeinsames Flag, eine so genannte Sperrvariable. Doch dabei muss man auf HT-Systemen besonders aufpassen.

Wartet ein Thread auf ein bestimmtes Ereignis eines anderen Threads, kann er a la "Loop until Sperrvariable true" eine Warteschleife durchlaufen. Auf einem SMP-System belastet dieses einfache Verfahren zwar eine CPU zu 100 Prozent mit Warten, der aktive Thread kann jedoch auf dem zweiten physikalischen Prozessor mit voller Performance weiterlaufen. Bei einer HT-CPU belegt diese kurze Warteschleife aber fast alle Ressourcen des physikalischen Prozessors. Der zweite Thread, auf den der erste ja wartet, läuft dadurch nur noch sehr langsam ab.

Deshalb sollte man in derartigen Schleifen zumindest den neuen Pentium-4-Befehl PAUSE integrieren. Er hält die Befehlsausführung für einige Takte an, ohne am Prozessorstatus etwas zu ändern. Dadurch kann der Thread auf der anderen logischen CPU für ein paar Takte mit voller Geschwindigkeit weiterlaufen. Auf älteren Intel-CPUs und AMD-Prozessoren wird die PAUSE-Instruktion als NOP (No Operation) interpretiert.

Besser ist es jedoch, auf eine derartige, handgestrickte Synchronisation der Threads ganz zu verzichten und die dafür optimierten Objekte des Betriebssystems zu nutzen. Microsoft stellt dafür beispielsweise die Objekte Mutex, Semaphore, Event und Critical Section zur Verfügung.