Multithreading


  • Administrator

    Hallo zusammen,

    Habe mich gerade letztens was gefragt. Bisher hatten wir ja eigentlich CPUs, welche nichts parallel ausführen konnten, sondern nur hintereinander. Sicher gab es Fälle, wo Multithreading ganz klar sinnvoll war, z.b. damit ein User, während einer Berechnung, trotzdem noch Eingaben machen konnte. Doch wie sinnvoll, bzw. welchen Gewinn an Berechnungszeit, hat zum Beispiel folgender Fall:
    Wir haben zwei Berechnungen, welche zum gleichen Zeitpunkt s starten und beim Zeitpunkt t beendet sein müssen. Sie hängen nicht voneinander ab, müssen keinen Input abwarten oder sonst was, es sind einfach nur zwei stink normale Berechnungen, z.b. 1 + 1. (Ganz billig 😉 )

    Auf einer alten CPU, also nicht Dual Core und co, hat hier Multithreading nichts gebracht oder? Ich meine, schlussendlich, wurde es trotzdem hintereinander ausgeführt. Es wäre ja sogar möglich, dass es einen Verlust bedeutet hat, da der Prozess zwischen Threads hin und her schalten muss. Oder lieg ich hier falsch?

    Wie sieht das denn bei den neuen Prozessoren aus? Wäre es sinnvoll, dann die zwei Berechnungen auf zwei Threads aufzuteilen? Grundsätzlich kann ja nun Arbeit wirklich parallel erledigt werden. Wie weit sollte man denn eigentlich nun mit Multithreading gehen?

    Zudem noch eine etwas speziferische Frage. Kann man eigentlich in den verschiedenen Sprachen, wie C, C++ (bzw. hier z.B. WinAPI / MFC / QT) oder Java usw. einen Thread einem Prozessor zuweisen? Also die Aufteilung und Verteilung der Last auf die Kerne selber übernehmen? Wenn ja, wie? ^^

    Grüssli



  • kenn mich da nicht so aus, aber:
    Ja, ich denke auf alten prozessoren wäre die version mit zwei threads langsamer gewsen, weil zusätzlich zur berechnung noch der overhead des umschalten zwischen den threads dazukommt.

    Auf neuen PCs mit zwei prozessoren ginge es mit zwei threads schneller, natürlich nur sofern die threads auf unterschiedliche speicherbereiche zugreifen, nciht aufeinander warten müsssen usw.

    Große Berechnungen sollte man glaub ich wenn es geht auf soviele threads aufteilen wie der pc prozessoren hat. DAnn hat jeder prozessor was zu tun. Nur aufpassen dass die threads sich nicht in die quere kommen.



  • Schau dir mal an, wie viele Prozesse/Threads aktuell auf deinem Betriebssystem laufen. ps aux | wc -l gibt bei mir 64 aus und da sind Threads noch nicht mal einberechnet. Dafür gibt es eben den Scheduler. Der Scheduler kümmert sich eben darum die Rechenzeit sinnvoll zu verteilen bzw. aufzuteilen. Ein Kern, Rechner oder CPU mehr gibt dem Scheduler eben mehr Rechenzeit, die er aufteilen kann.

    Multithreading/processing (oder wie man es nennt) sorgt also dafür, dass die Programme leichter skalieren. Habe ich ein Programm, dass die Arbeit auf n-Threads aufteilt, dann kann ich es eben skalieren, wenn ich mehr Rechner/Kerne/CPUs hinzufüge. Das ist der ganze Sinn hinter dem Multithreading.

    Multithreading bedeutet nicht, dass das Programm schneller läuft. Da kommt eben Verwaltungsaufwand hinzu (Task-Switches sind im Grunde egal, da der Scheduler ja eh alle 1/n Sekunden unterbricht). Multithreading bedeutet nur, dass das Programm schneller laufen kann wenn ich mehr Rechner/Kerne/CPUs hinzufüge. Das ist ein Unterschied!

    Und es gibt auch Systeme/Programmiersprachen, die einen dazu auffordern für alles einen "Thread" (irgend wie finde ich den Begriff unpassend, weil man unter einem Thread idr. so etwas wie einen POSIX/Windows-Thread versteht) zu nehmen. Hier sei besonders Erlang erwähnt.

    btw. ja man kann bei vielen Betriebssystemen angeben, dass die "Threads" auf unterschiedlichen CPUs ausgeführt werden sollen. (Unter OSX geht das mit dem CHUD-Framework. Für andere Betriebssystem weiß ich es nicht)



  • Dravere schrieb:

    Zudem noch eine etwas speziferische Frage. Kann man eigentlich in den verschiedenen Sprachen, wie C, C++ (bzw. hier z.B. WinAPI / MFC / QT) oder Java usw. einen Thread einem Prozessor zuweisen? Also die Aufteilung und Verteilung der Last auf die Kerne selber übernehmen? Wenn ja, wie? ^^

    Ja, das kannst du machen, in der WinAPI z. B. hiermit: http://msdn2.microsoft.com/en-us/library/ms686223.aspx

    In der Regel solltest du das aber den OS-Scheduler machen lassen, der ist schliesslich dafuer gemacht und hat mehr Ueberblick als du 😉



  • Task-Switches sind im Grunde egal, da der Scheduler ja eh alle 1/n Sekunden unterbricht

    Nope, ist nicht egal. Der Scheduler läuft zwar an, bloss wenn der sieht dass nix umgeschaltet werden braucht ist die ganze Sache doch schneller als wenn er switchen muss. Schon alleine deswegen weil der Inhalt des Cache grösstenteils erhalten bleibt, aber ich hoffe mal schwer dass der Fall "kein Umschalten nötig" auch so noch optimiert wurde.



  • hustbaer schrieb:

    Task-Switches sind im Grunde egal, da der Scheduler ja eh alle 1/n Sekunden unterbricht

    Nope, ist nicht egal. Der Scheduler läuft zwar an, bloss wenn der sieht dass nix umgeschaltet werden braucht ist die ganze Sache doch schneller als wenn er switchen muss. Schon alleine deswegen weil der Inhalt des Cache grösstenteils erhalten bleibt, aber ich hoffe mal schwer dass der Fall "kein Umschalten nötig" auch so noch optimiert wurde.

    Naja, die Unterbrechung springt aber in den Kernel-Mode. Sprich es gibt immer einen Task-Switch. (Ich gehe mal von den gewöhnlichen Architekturen aus. Ein Userspace Scheduler könnte das natürlich anders machen).

    Und auf einem normalen Desktop Betriebssystem dürfte es auch kaum einen "kein Umschalten nötig" Fall geben.



  • rüdiger schrieb:

    Und auf einem normalen Desktop Betriebssystem dürfte es auch kaum einen "kein Umschalten nötig" Fall geben.

    wenn nur ein thread auf höchster prioritätsstufe in einer endlosschleife läuft, kommen die anderen nie dran. dann hängt aber auch die ganze kiste...



  • pale dog schrieb:

    rüdiger schrieb:

    Und auf einem normalen Desktop Betriebssystem dürfte es auch kaum einen "kein Umschalten nötig" Fall geben.

    wenn nur ein thread auf höchster prioritätsstufe in einer endlosschleife läuft, kommen die anderen nie dran. dann hängt aber auch die ganze kiste...

    hängt vom Scheduler ab 🙂 und klar kann er in dem Fall einfach dem Prozess die komplette Rechenzeit geben und sich ausschalten. Aber das ist ja ein sehr seltener Fall...



  • Für Threads gilt der alte Spruch: So wenige wie möglich, soviele wie nötig.

    Threads "beschleunigen" nichts, sie kosten Performance. Je mehr Threads, desto mehr Overhead aka verschwendete Rechenzeit. Da Threads also Kosten haben, muß man sich klarmachen in welchem Zusammenhang sie denn Nutzen bringen.

    Der Hauptsinn von Threads liegt in der Entkopplung von Aktivitäten. z.B. willst Du ja gerne noch deinen Rechenr bedienen können während der Browser gerade Daten aus dem Internet lädt. Threads geben Dir die Möglichkeit verschiedene Sachen auf deinem Rechern zu machen die sich aber nciht gegenseitig blockieren. Ein Nebeneffekt davon ist, das die Prozessorleistung optimaler ausgenutzt werden kann.

    Jedoch an dem Beispiel mehrerer Berrechnungen kann man durch Multithreading theoretisch sogar einen Performancenacheil erzeugen, weil moderne CPUs durchaus in der Lage sind gewisse Aktivitäten quasi-gleichzeitig zu erledigen. Ohne den Mechanismus jetzt eingehend beschreiben zu wollen soviel: CPUs können bestimmte Operationen in Teilschreitte zerlegen und die Teilschritte mehrerer Operationen "ineinander verschachteln".

    z.B. würden dann 4 Multiplikationen nicht die Dauer von 4 einzelnen Multiplikationen haben, sondern insgesamt sogar in der Zeit von 2 Multiplikationen ablaufen. (Wohl gemerkt, auf nur einer CPU). Dies klappt aber nur weil die 4 Multiplikationen auf der gleichen CPU laufen. Verteilt man die statt dessen auf mehrere CPUS geht die Möglichkeit des Schachtelns verloren... Man braucht unterm Strich auf einmal wieder länge weil ja auch ein gewisser Threading-Overhead hinzukommt.



  • rüdiger schrieb:

    pale dog schrieb:

    rüdiger schrieb:

    Und auf einem normalen Desktop Betriebssystem dürfte es auch kaum einen "kein Umschalten nötig" Fall geben.

    wenn nur ein thread auf höchster prioritätsstufe in einer endlosschleife läuft, kommen die anderen nie dran. dann hängt aber auch die ganze kiste...

    hängt vom Scheduler ab 🙂 und klar kann er in dem Fall einfach dem Prozess die komplette Rechenzeit geben und sich ausschalten. Aber das ist ja ein sehr seltener Fall...

    naja, abschalten wird er sich nicht dabei. die CPU bekommt ja noch (alle 50mS oder so) einen interrupt, der den scheduler antickert. jener guckt erstmal nach ob die zeit des threads abgelaufen ist, ist das der fall, dann schaut er in seiner liste nach, ob ein weiterer thread auf gleicher (der höchsten) priostufe laufen will, findet keinen, und teilt dem selben thread wieder eine neue zeitscheibe zu.
    ...und falls das eine miese CPU ist, die nur einen instruction cache hat, wirkt sich der periodische scheduler-interrupt auf die performance recht negativ aus.
    multithreading ist aus gescwindigkeitsgründen gar keine tolle sache. es ist nur gut für programmierer, die sonst (ohne multithreading) einen haufen ineinander verschachtelter statemachines und coroutines basteln müssten...
    🙂



  • pale dog schrieb:

    rüdiger schrieb:

    pale dog schrieb:

    rüdiger schrieb:

    Und auf einem normalen Desktop Betriebssystem dürfte es auch kaum einen "kein Umschalten nötig" Fall geben.

    wenn nur ein thread auf höchster prioritätsstufe in einer endlosschleife läuft, kommen die anderen nie dran. dann hängt aber auch die ganze kiste...

    hängt vom Scheduler ab 🙂 und klar kann er in dem Fall einfach dem Prozess die komplette Rechenzeit geben und sich ausschalten. Aber das ist ja ein sehr seltener Fall...

    naja, abschalten wird er sich nicht dabei. die CPU bekommt ja noch (alle 50mS oder so) einen interrupt, der den scheduler antickert. jener guckt erstmal nach ob die zeit des threads abgelaufen ist, ist das der fall, dann schaut er in seiner liste nach, ob ein weiterer thread auf gleicher (der höchsten) priostufe laufen will, findet keinen, und teilt dem selben thread wieder eine neue zeitscheibe zu.
    ...und falls das eine miese CPU ist, die nur einen instruction cache hat, wirkt sich der periodische scheduler-interrupt auf die performance recht negativ aus.

    Er könnte sich aber abschalten, bis ein neuer Prozess gestartet wird. Aber wie gesagt. Das ist ja eh eine Ausnahme das man ein Prozess hat, der alle Rechenzeit bekommt und ist hier sicher auch kein geeignetes Beispiel...

    Wobei der Fall ja eh nur auf einem ein Prozessor System funktioniert. Hat man zB einen anderen Kern, dann kann dort ein Prozess niedriger Priorität laufen.



  • Eeventuell ist auch eine gewisse Energieersparnis möglich. Zwei niedriger getaktete Prozessoren schaffen dann das gleiche wie ein höher getakteter Prozessor, benötigen dafür aber weniger Energie.



  • skals schrieb:

    Für Threads gilt der alte Spruch: So wenige wie möglich, soviele wie nötig.

    Threads "beschleunigen" nichts, sie kosten Performance. Je mehr Threads, desto mehr Overhead aka verschwendete Rechenzeit. Da Threads also Kosten haben, muß man sich klarmachen in welchem Zusammenhang sie denn Nutzen bringen.

    Wie gesagt, ein großer Vorteil von Threads ist, dass die Software besser skaliert.



  • rüdiger schrieb:

    Er könnte sich aber abschalten, bis ein neuer Prozess gestartet wird.

    wie soll denn ein neuer prozesses/thread gestartet werden, wenn der scheduler nicht läuft?

    rüdiger schrieb:

    Wobei der Fall ja eh nur auf einem ein Prozessor System funktioniert. Hat man zB einen anderen Kern, dann kann dort ein Prozess niedriger Priorität laufen.

    natürlich, hat man mehrere kerne, dann sollten die alle gut beschäftigt werden. ein multiprozessor-kernel würde in dem fall, wenn auf einem kern nur ein einziger high-priority thread läuft, andere threads mit niedrigeren prioritätsstufen auf anderen kernen ausführen. bei einem single-prozessor system müssten die warten.

    Jester schrieb:

    Eeventuell ist auch eine gewisse Energieersparnis möglich. Zwei niedriger getaktete Prozessoren schaffen dann das gleiche wie ein höher getakteter Prozessor, benötigen dafür aber weniger Energie.

    ich glaub' nicht.



  • pale dog schrieb:

    Jester schrieb:

    Eeventuell ist auch eine gewisse Energieersparnis möglich. Zwei niedriger getaktete Prozessoren schaffen dann das gleiche wie ein höher getakteter Prozessor, benötigen dafür aber weniger Energie.

    ich glaub' nicht.

    Ich weiß es. 🙂 Leider kann ich den Link zu den entsprechenden Vorlesungsfolien nicht posten, weil der Assistent die bei ner Korrektur mit nem falschen Foliensatz überschrieben hat.



  • Jester schrieb:

    pale dog schrieb:

    Jester schrieb:

    Eeventuell ist auch eine gewisse Energieersparnis möglich. Zwei niedriger getaktete Prozessoren schaffen dann das gleiche wie ein höher getakteter Prozessor, benötigen dafür aber weniger Energie.

    ich glaub' nicht.

    Ich weiß es. 🙂 Leider kann ich den Link zu den entsprechenden Vorlesungsfolien nicht posten, weil der Assistent die bei ner Korrektur mit nem falschen Foliensatz überschrieben hat.

    vielleicht liegt es daran, dass beim erhöhen der taktfrequenz der energieverbrauch quadratisch o.ä. ansteigt, während beim hinzufügen eines zweiten prozessors sich dieser nur verdoppelt?



  • Wieso sollte die Verlustleistung denn quadratisch steigen? Also bei gleichen Randbedingungen (Spannung, Architektur, Fertigung)?



  • pale dog schrieb:

    rüdiger schrieb:

    Er könnte sich aber abschalten, bis ein neuer Prozess gestartet wird.

    wie soll denn ein neuer prozesses/thread gestartet werden, wenn der scheduler nicht läuft?

    Äh? Dein Modell war doch folgendes: Es wird kein neuer Task ausgewählt, wenn wir einen Task haben der mit der höchsten Priorität läuft. Also welchen Task soll er dann auswählen? Keinen... Da wäre es wohl eine Optimierung den Scheduler auszuschalten, bis man einen neuen Task hinzufügt. Aber ich hab keine Lust über diesen Fall mehr zu reden. Der ist sinnlos und künstlich konstruiert und bringt uns nicht weiter.



  • pale dog schrieb:

    Jester schrieb:

    pale dog schrieb:

    Jester schrieb:

    Eeventuell ist auch eine gewisse Energieersparnis möglich. Zwei niedriger getaktete Prozessoren schaffen dann das gleiche wie ein höher getakteter Prozessor, benötigen dafür aber weniger Energie.

    ich glaub' nicht.

    Ich weiß es. 🙂 Leider kann ich den Link zu den entsprechenden Vorlesungsfolien nicht posten, weil der Assistent die bei ner Korrektur mit nem falschen Foliensatz überschrieben hat.

    vielleicht liegt es daran, dass beim erhöhen der taktfrequenz der energieverbrauch quadratisch o.ä. ansteigt, während beim hinzufügen eines zweiten prozessors sich dieser nur verdoppelt?

    das haengt von der aufgabe ab und natuerlich den verglichenen prozessoren. normalerweise skalieren anwendungen nicht 1:1 mit mehr cores, so im schnitt, wenn sie darauf ausgelegt sind mehr cores zu nutzen, hast du mit zwei cores 80% mehr rechenleistung. also ist die energieeffiziens schonmal leicht verschlissen. zudem haengt das von der taktung ab, denn wie du gesagt hast, steigt das eine eher quadratisch und das andere linear. wenn du also zwei kerne bei 1GHz hast und mit einem 2GHz vergleichst, dann werden beide cpus in etwa gleich ziehen.



  • Am besten gleich ein eigenes OS, nur dann kann man Multifreding richtig ausnutzen... 🙄



  • Mit google findet man auch ein paar Sachen zur Energieersparnis: ftp://ftp-sop.inria.fr/pub/rapports/RR-3621.ps.gz


Anmelden zum Antworten