Hyperthreading führt Prozessprioritäten ad absurdum


  • Mod

    Bei Prozessoren die mit Hyperthreading ausgestattet sind (oder wie immer das AMD-Äquivalent heißt) ist die Idee ja, dass zwei Prozesse sich einen CPU-Kern teilen und diese beide dadurch insgesamt schneller fertig sind, als wenn man sie nacheinander auf einem Kern ausführt, weil Wartezeiten des einen Prozesses produktiv vom anderen Prozess genutzt werden können. Jeder einzelne Prozess ist dabei aber nur ungefähr halb so schnell als wenn er alleine ausgeführt würde (der Unterschied zu 50% ist dann der Geschwindigkeitsgewinn).

    Jetzt ist mir aber ein Problem aufgefallen: Die Hyperthreadingabstraktion findet im Computer auf ganz tiefer Ebene statt, das Betriebssystem sieht statt einem Kern zwei Kerne. Und das bringt die Scheduler durcheinander: Wenn man einen Prozess mit sehr niedriger Priorität hat und einen mit sehr hoher, dann bekommen beide jeweils einen Kern zugewiesen (sofern nichts anderes läuft). So sollte es bei einem Zweikernsystem ja auch sein: Der Prozess mit der hohen Priorität bekommt einen ganzen Prozessor zu 100%. Der andere Kern hat aber nichts zu tun, also kann da auch der Prozess mit der niedrigen Priorität laufen, denn der Prozess mit der hohen Priorität wird nicht schneller oder langsamer weil der andere Kern beschäftig/unbeschäftigt ist. Bei Hyperthreading ist dies aber nicht so! Eine Belastung des anderen virtuellen Kerns hat zur Folge, dass der Prozess mit der hohen Priorität nur 50% der theoretisch verfügbaren Ressourcen zur Verfügung hat und der Prozess mit der niedrigen Priorität ebenfalls. Das heißt, der Prozess mit der niedrigen Priorität bremst das System zu ca. 50% aus!

    Kennt jemand Abhilfe für das Problem? Vorzugsweise für Linux-Systeme, aber auch eine allgemeine Antwort würde mich interessieren, denn mir selbst fällt keine einfache Strategie zur Lösung ein. Eine einfache Änderung des Schedulers würde jedenfalls nicht reichen. Aber vielleicht haben andere Leute ja schon etwas länger darüber nachgedacht als ich und eine gute Lösung entwickelt.

    Wenn ich im Netz nach der Problemstellung suche, finde ich leider nur Leute mit der gleichen Frage (erstaunlich wenige noch dazu, fällt anscheinend nicht so auf), aber keine Antworten. Die Antwort kann ja wohl nicht sein, Hyperthreading abzuschalten, oder? Aber ich fürchte die Antwort dürfte irgendwie auf Prioritätssteuerung auf Prozessorebene hinauslaufen.



  • Hyperthreading abschalten.

    Hyperthreading ist nur für eins gut: die Kerne stärker auszulasten. Wenn du den Kern aber schon selber auslasten kannst, dann schadet Hyperthreading nur.

    PS:
    unter OS X kannst du hyperthreading zB per

    $ hwprefs cpu_ht=false
    

    ein bzw mit true wieder anschalten.

    Unter Linux gibt es sicher etwas vergleichbares


  • Mod

    Shade Of Mine schrieb:

    Hyperthreading ist nur für eins gut: die Kerne stärker auszulasten. Wenn du den Kern aber schon selber auslasten kannst, dann schadet Hyperthreading nur.

    Danke für die Erklärung.

    Shade Of Mine schrieb:

    Unter Linux gibt es sicher etwas vergleichbares

    Cool. Angeblich geht das während des Betriebs, indem man einfach in /sys/devices/system/cpu/ in die Dateien cpuX/online eine 0 beziehungsweise eine 1 schreibt. Ich vertraue da zwar eigentlich den Kernelentwicklern, dass das auch funktioniert, aber irgendwie traue ich mich doch nicht, das auf dem Rechner im Produktivlauf zu machen. Wenn der Rechner wieder frei ist, werde ich das mal ausprobieren.

    Und natürlich werde ich mal ausprobieren was passiert, wenn ich alle Kerne auf 0 setze.



  • "Ad absurdum führen" ist mMn. ein viel zu starker Ausdruck.

    HT kann dazu führen dass die Latenz von hochpriorisierten Tasks steigt. Der Troughput eines Systems sollte davon aber in den meisten Fällen nicht negativ beeinflusst werden. Kann eigentlich nur sein, wenn ein System unwichtige Tasks mit niedrigerer Priorität laufen lässt, in der Meinung dass sie eh nur laufen wenn sie nix anderes bremsen.

    Das stimmt allerdings nichtmal auf echten Mehrkernsystemen ohne HT, denn es gibt immer Resourcen die sich die Kerne eines Systems teilen müssen. Speicher, bei Mehrkernsystemen mit gemeinsamem Cache auch dieser, und auch Dinge wie OS-Mutexen etc.

    HT führt also im Vergleich zu echten Mehrkernsystemen nur zu einer Verstärkung eines sowieso schon vorhandenen Effekts.

    ----

    Shade Of Mine schrieb:

    Hyperthreading ist nur für eins gut: die Kerne stärker auszulasten. Wenn du den Kern aber schon selber auslasten kannst, dann schadet Hyperthreading nur.

    Der überwiegende Grossteil der Programme kann das aber nicht - das ist schliesslich der Grund warum HT überhaupt erfunden wurde. Und die die es können, können auch oft nahezu beliebig viele Kerne/Threads beschäftigen, so dass niederpriorisierte Tasks gar nicht stören könnten.

    ----

    Ich sehe kaum einen Grund HT jemals abzudrehen. Interrupt Latency geht zurück, die Responsiveness des Systems steigt, der Throughput steigt - was will man mehr?



  • [quote="hustbaer"]

    Ich sehe kaum einen Grund HT jemals abzudrehen. Interrupt Latency geht zurück, die Responsiveness des Systems steigt, der Throughput steigt - was will man mehr?

    Ein QuadCore ist ohne HT deutlich schneller als mit HT.

    Das Problem ist naemlich, dass du durch HT deine maximal Leistung um etwa 30% reduzierst. Und sobald du 3 Kerne oder mehr hast, aendert sich die responsiveness ja auch nicht wirklich: denn wieviele Threads locken gerade?

    Jedesmal wenn ein Core auf 100% last geht - ist HT schlecht. HT ist dann ideal wenn du viele Prozesse auf 10-30% Last hast. Wenn das dein Umfeld ist, ist HT super. Wenn du zB kompilierst, video encoding/video schnitt, etc. betreibst ist HT dagegen schlecht.



  • @Shade Of Mine:
    Mal als Beispiel:
    http://mos.techradar.com/techradar-corei7-benchmarks.pdf
    Ganz unten, "HT Benchmarks". Durch die Bank schneller mit HT=on.

    Oder:
    http://vr-zone.com/articles/does-core-i7-hyper-threading-helps-/6160.html
    Zwei Tests deutlich schneller (+34% und +16%), zwei etwas langsamer (-5% und -0.7%). Im Schnitt als auch ein Gewinn mit HT=on.

    Ein QuadCore ist ohne HT deutlich schneller als mit HT.

    Das Problem ist naemlich, dass du durch HT deine maximal Leistung um etwa 30% reduzierst.

    Nö. Die Leistung sinkt nur dann, wenn auf beiden virtuellen CPUs des HT-Paares gleichzeitig was läuft. Läuft dagegen nur auf einer virtuellen CPUs des HT-Paares war, liefert diese auch volle Leistung.

    Und da der Windows-Scheduler ab spätestens 2003/Vista "HT-aware" ist, tut er auch nicht zwei Threads auf einem HT-Paar schedulen, wenn <= N Threads "runnable" sind (mit N = anzahl der "echten" Cores).

    Und sobald du 3 Kerne oder mehr hast, aendert sich die responsiveness ja auch nicht wirklich: denn wieviele Threads locken gerade?

    Das stimmt, ja. Nen wirklich spürbaren Gewinn bei Responsiveness gibt es nur auf Systemen mit Single-Core CPUs ala P4 oder Single-Core Atom'.

    p.S.: was den Linux Scheduler oder andere angeht kann ich diesbezüglich nur hoffen dass die auch HT-aware sind, wissen tu ich es aber nicht.



  • HT ist doch vor allem dazu da, Prozesse besser verzahnt in die Pipline zu schieben und so Verzögerungen zu minimieren.
    Der Verbesserungseffekt hängt von der Verzögerung im Betriebssystem ab.
    Wenn schon einiges oder alles z.B. Cache optimiert ist, dann brauchts kein HT.
    (Und für gute Asmprogramme auch nicht unbedingt)

    Ich denke HT ist auch mehr für den Allgemeinbetrieb auf Hochsprachenebene gedacht, und nicht primär als Spezialrechnerei-Tuningtool.



  • nachtfeuer schrieb:

    HT ist doch vor allem dazu da, Prozesse besser verzahnt in die Pipline zu schieben und so Verzögerungen zu minimieren.
    Der Verbesserungseffekt hängt von der Verzögerung im Betriebssystem ab.
    Wenn schon einiges oder alles z.B. Cache optimiert ist, dann brauchts kein HT.
    (Und für gute Asmprogramme auch nicht unbedingt)

    Ne.
    Ohne HT bekommt man es auch mit "guten Asmprogrammen" nicht hin sämtliche Teile eines Cores auszulasten. In Spezielfällen mag es gehen, aber da man sich meist nicht aussuchen kann was man programmieren muss sonder nur wie, wird auch der begabteste Assembler Programmierer die allermeisten Programme nicht so hinbekommen dass sie die CPU ohne HT voll auslasten.

    Ich denke HT ist auch mehr für den Allgemeinbetrieb auf Hochsprachenebene gedacht, und nicht primär als Spezialrechnerei-Tuningtool.

    Denk nicht so viel 🤡



  • hustbaer schrieb:

    p.S.: was den Linux Scheduler oder andere angeht kann ich diesbezüglich nur hoffen dass die auch HT-aware sind, wissen tu ich es aber nicht.

    Seit etwa einem Jahrzehnt sowas IIRC. Plus minus ein Jahr. (Erinnere mich dunkel an entsprechende 2.5er-Changelogs und Backports zu 2.4.x.)

    Ich finde das Thema ehrlich gesagt nicht spannend genug, um selbst zu suchen, aber etwas ausführlichere Benchmarks als die bis dato geposteten fände ich trotzdem fein, wenn Ihr gerade zufällig was bei der Hand habt. 🙂

    Ich selbst würde HT nicht abschalten, aber ein echtes CPU-Kaufargument ist es für mich auch nicht. (Da sind die größeren Caches der entsprechenden Intel-CPUs in meinen Augen schon viel interessanter.) Lass mich natürlich gerne eines besseren belehren, sofern irgendjemand gute Benchmarks oder sonstige Daten hat.



  • Shade Of Mine schrieb:

    Hyperthreading ist nur für eins gut: die Kerne stärker auszulasten.

    Allerdings wirkt sich dies als Steigerung der Prozessorleistung aus.

    Shade Of Mine schrieb:

    Wenn du den Kern aber schon selber auslasten kannst, dann schadet Hyperthreading nur.

    Kannst du das? Nun ich bin wirklich kein Prozessor-Assembler-Kenner, allerdings kenn ich die Motivation, dass im Befehl/Datenstrom Abhängigkeiten existieren, dass den Prozessorscheduler verhindet, den Befehlsstrom durchgängig in die Pipeline zu schieben, aus diesen Grund wurde HT entwickelt.



  • hustbaer schrieb:

    Ohne HT bekommt man es auch mit "guten Asmprogrammen" nicht hin sämtliche Teile eines Cores auszulasten. In Spezielfällen mag es gehen, aber da man sich meist nicht aussuchen kann was man programmieren muss sonder nur wie, wird auch der begabteste Assembler Programmierer die allermeisten Programme nicht so hinbekommen dass sie die CPU ohne HT voll auslasten.

    Ht ist kein Auslastungsgarant, es bietet Verzögerungsminimierung und bessere Effizienz. Multiprozessing steckt noch nicht mal in den Kinderschuhen, krabbelt auch noch auf allen Vieren. Ich hab noch kein wirklich gutes Multiprozessorprogrammiertool gesehen. Und vor allem hängt die Auslastung der Kerne von der Parallelisierbarkeit des Programms selbst ab und dem Programmierer Know How, das ganze auch umzusetzen.



  • OK das war vielleicht ein wenig misverständlich formuliert.

    Ich meinte damit: es ist beim grossteil der Programme noch Potential da, das man mit HT nutzen kann, um den gesamten Throughput zu steigern.
    Parallelisierbarkeit vorausgesetzt.

    Multiprozessing steckt noch nicht mal in den Kinderschuhen, krabbelt auch noch auf allen Vieren. Ich hab noch kein wirklich gutes Multiprozessorprogrammiertool gesehen.

    Ich würde mal sagen das ist Definitionssache. Kann man über viele Bereiche sagen. Bei IDEs ist mMn. z.B. auch noch gewaltig viel Raum für Verbesserungen. Trotzdem finde ich z.B. Visual Studio 2010 in Verbindung mit Visual Assist X sehr gut.

    Genau so gibt es einige recht brauchbare Techniken/Libs für Parallelprogrammierung.

    Und vor allem hängt die Auslastung der Kerne von der Parallelisierbarkeit des Programms selbst ab und dem Programmierer Know How, das ganze auch umzusetzen.

    Ja. Aber wo ist das schon anders? Die Qualität von jedem Programm hängt von den Fähigkeiten des Entwicklers ab. Wie sollte es auch anders sein?

    ----

    Mir ging es lediglich darum dass HT (im Allgemeinen) die Performance nicht verschlechtert, so wie Shade es dargestellt hat.


  • Mod

    Ja, die Gesamtleistung steigt sicherlich, weil beide Prozesse den Prozessor optimal auslasten. Das Problem ist aber trotzdem da, dass Prozesspriorität dadurch nicht mehr richtig funktioniert. Gerade bei prozessorlastigen Programmen will man diese schließlich benutzen. Wenn die Programme ohnehin durch andere Ressourcen beschränkt sind, nützt Prozesspriorität herzlich wenig zur Steuerung.

    Jedenfalls stehen so einem Prozess der sonst 99.999% der CPU-Zeit bekäme, nur 50% zur Verfügung. Auch wenn der Gesamtumsatz der CPU dafür um 10% steigt, gleicht sich das doch niemals aus. Die Möglichkeit, HT abzuschalten scheint wohl der einzig gangbare Weg zu sein, wenn man die Prioritäten benutzen möchte. Der Scheduler kann ja gerne wissen, dass einer der Kerne nur virtuell ist - mir fällt jedenfalls keine Möglichkeit ein wie er die Prozessorzeit trotzdem wie gewünscht aufteilen könnte, außer nur auf einem der Kerne zu rechnen.



  • SeppJ schrieb:

    Der Scheduler kann ja gerne wissen, dass einer der Kerne nur virtuell ist - mir fällt jedenfalls keine Möglichkeit ein wie er die Prozessorzeit trotzdem wie gewünscht aufteilen könnte, außer nur auf einem der Kerne zu rechnen.

    Was gefällt dir an der Lösung, dass in solchen extremsituationen der Scheduler den virtuellen core nichts tun lässt, nicht? Man könnte das auch noch weiter denken. Jedenfalls käme dann am Ende raus, dass das alles gar kein Problem ist, wenn der Scheduler schlaug genug ist.



  • Das Problem ist, wenn ein hoch priorisierter Prozess und ein niedrig priorisierter Prozess sich die CPU Pipeline teilen, bekommen Sie 50-50 Zeitanteile, d.h. im Endeffekt bekommen Sie gleiche Zeitanteile bereitgestellt. Ich habs mit C# auf Win7 getest.



  • Ich gebs auf.
    Tut was ihr für richtig haltet, dreht es auf oder ab, ganz wie es euch gefällt.
    Ich sehe zwar kein Problem, aber wenn ihr dann besser schlafen könnt ... geht ja um nix.



  • Wie kann hyperthreading Prioritaeten ad absurdum fuehren, wenn es keine Prioritaeten kenn. Diese werden erst durch das Betriebssystem hinzugefuegt.


  • Mod

    knivil schrieb:

    Wie kann hyperthreading Prioritaeten ad absurdum fuehren, wenn es keine Prioritaeten kenn. Diese werden erst durch das Betriebssystem hinzugefuegt.

    Und die Betriebssysteme kommen damit nicht zurecht. Wem du jetzt die Schuld gibst, ist mir egal. Fakt ist, es funktioniert nicht wie es soll.

    edit: Und eine mögliche Lösung wäre natürlich, wenn der Prozessor selbst Prioritäten kennen würde. Es ist aber einsichtig, dass dies ziemlich viel Entwicklungsarbeit bei den Prozessorentwicklern voraussetzen würde, die ich dann doch lieber bei schnelleren oder billigeren Chips sehen würde. Wie Shade of Mine schon sagte, kann man bei Bedarf die Kerne on the fly deaktivieren und hat dann das Problem für sich gelöst, auch wenn dies die Gesamtleistung um ein paar Prozent senken wird.


Anmelden zum Antworten