AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread auf mehrere Core verteilen

Ein Thema von EWeiss · begonnen am 18. Sep 2013 · letzter Beitrag vom 20. Sep 2013
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    
EWeiss
(Gast)

n/a Beiträge
 
#11

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:10
Zitat:
Das findet aber alles außerhalb der Pascal Welt statt.
Danke!

Ja leider..

gruss
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#12

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:16
Thread sind doch gerade das Werkzeug, um einen MultiCore Prozessor auszunutzen!

Ein Thread ist quasi ein Ablauf, wo der Programmierer gesagt hat: "So, das Zeug muss schön sequenziell ablaufen."
Wenn du jetzt mehrere Threads erzeugst, sagst du ja genau "Diese Code-Abschnitte müssen jeder für sich sequenziell ablaufen, aber die Abschnitte sind voneinander unabhängig"

Daraus folgt auch, dass es nicht sinnvoll ist, einen Thread auf mehrere Kerne zu verteilen: da die Anweisungen streng sequenziell ablaufen müssen, hat ein zweiter Kern einfach nichts zu tun. Sie könnten sich natürlich einfach ständig abwechseln. Dann hättest du 50% Auslastung auf jedem Kern. (Passiert in der Praxis auch oft)

Zitat:
Ich verstehe nicht warum ein System nicht in der lage ist zu erkennen wenn ein core ausgelastet ist
um dann diesen auf die übrigen zu verteilen.
Das Betriebssystem kann da eigentlich nicht mehr parallelisieren was der Programmierer verschlafen hat. Was es selbstverständlich macht: Zwei Threads, die beide Rechnen wollen, auf zwei verschiedene Kerne aufteilen.
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#13

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:22
Zitat:
Wenn du lediglich das Hängen der Anwendung vermeiden willst, reicht es ja schon, wenn du die Berechnung insgesamt in einen eigenen Thread verlagerst.
Hab ich ja schon..
Einen der nur für die berechnungen zuständig ist.

Ich verstehe nicht warum ein System nicht in der lage ist zu erkennen wenn ein core ausgelastet ist
um dann diesen auf die übrigen zu verteilen.
Was für einen Sinn hat sonst ein 4 Kern prozessor wenn er nicht dynamisch vom system verwaltet wird
um eventuelle auslastungen eines Kerns zu verhindern.
Doch. Genau das macht das System (bzw. Konkret: Der sogenannte 'Scheduler' des Betriebssystems) ja auch.

Bitte versteh das jetzt nicht falsch, aber mir scheint Dir fehlen ein bisschen die Grundlagen beim Multithreading.
Versuchen wir das also mal aufzuräumen, dann verstehst Du auch die Problematik dahinter und siehst vielleicht auch Lösungsansätze bei Deinem konkreten Problem.

Erstens: Multithreading kommt von multiple threads. Nicht von einen Thread (Faden) auf mehrere CPUs/Kerne verteilen.

Das Betriebsystem (bzw. wieder der Scheduler), verwaltet mehrere Prozesse. Jeder Prozess hat mindestens einen (Haupt-)Thread und kann daneben noch mehrere andere Nebenläufige Threads haben.

Der Scheduler kann nun die einzelnen Threads der unterschiedlichen Prozesse je nach ihrer Priorität auf die verfügbaren Kerne verteilen.
Damit irgendwann mal alle Prozesse laufen, kann ein gerade laufender Thread zu jedem beliebigen Zeitpunkt eingefroren und ein anderer Thread (ggf. des gleichen oder eines anders Prozesses) an dem Zeitpunkt seines letztens Einfrierens weitergelaufen lassen werden. Diesen Wechsel des gerade ausgeführten Threads auf einem Kern nennt man Kontextwechsel (und das ist ein relativ teurer Prozess, da dabei der Teil des Programmes mit allen Daten im Stack-Speicher aus allen Registern des Kerns und dem jeweiligen First- und Second-Level Cache der CPU in einen anderen Speicherbereich kopiert wird, und der neue Thread mit allen seinen aktuellen Nutzdaten in die Register der CPU und die Caches reinkopiert werden muss).

Daraus ergibt sich dann auch folgendes: Mehr Threads = mehr Kontextwechsel = mehr Rechenaufwand. Ab einer gewissen Anzahl an Threads wird Multithreading also sogar wieder Kontraproduktiv.

Zurück zum Thread: Einer davon kann immer nur auf genau einem Kern laufen.

Ein Thread ist dabei der Ablauf eines konkreten Pfades in einem Programm.
Stelle Dir z.B. eine längere Funktion vor, die Du programmiert hast. Diese Funktion wird Operation für Operation nacheinander auf einem Kern abgearbeitet. Dabei kann es *jederzeit* zwischen zwei Operationen zu einem STOP Deiner Programmausführung und zu einem Kontextwechsel kommen (z.B. Dein Audioplayer berechnet die nächsten 15ms Soundausgabe vor). Danach läuft dann Dein Programm wieder weiter.

Wie würdest Du nun versuchen wollen, diese lange Funktion auf zwei Kernen gleichzeitig auszuführen?
Das ist unmöglich, denn die Operationen in Deiner Funktion müssen ja nacheinander ausgeführt werden, oder?
Stell Dir vor Du hast ein Programm mit 64 Zeilen Code. Und einen Rechner mit 64 Kernen. Und alle Kerne würden absolut Zeitgleich(!) beginnen, jeweils eine Zeile Deines Programmes abzuarbeiten. Ginge das? Was ist, wenn Zeile 63 eine Variable Benötigt, die erst in Zeile 30 berechnet wird, und zwar aus Werten die aus Zeile 4 und 5 kommen?
Da ein Kern nicht in die Zukunft sehen kann, und die anderen Kerne ja noch nicht mit ihrer Berechnung fertig sind, müsste er warten, bis alle vorherigen Kerne jeweils ihre eine einzige Operation ausgeführt haben. Dann kann das auch gleich nur auf einem Kern laufen.

Dir bleibt also nur, zu einem *definierten* Zeitpunkt in Deinem Programm zu sagen, dass ein neuer Thread gestartet wird.
Diesem gibst Du eine Methode mit, die dann in diesem anderen Thread abgearbeitet wird.

Dieser Thread läuft möglicherweise(!) parallel zu Deinem Hauptthread ab. Oder hinterher. Oder vorher. Du hast hier kaum Einfluss darauf, da der Scheduler des Betriebssystems die Threads auf die Kerne verteilt. Ist die Methode die in dem Thread ablaufen soll dann Zuende berechnet und folgen keine weiteren Anweisungen mehr, so wird der Thread beendet. Die anderen Threads Deines Programmes haben lediglich die Möglichkeit (solange sie gerade laufen), andere Deiner Threads ggf. zu pausieren, pausierte wieder zu starten oder zu beenden. Solange ein Thread pausiert, wird er vom Scheduler nicht mehr eingesetzt.

So, bleibt nur noch ein Problem: Die Synchronisierung.

Alle Threads Deines Prozesses haben Zugriff auf den gleichen (Heap-) Speicher. Lediglich der Stack ist pro Thread separat.
Wenn Du also ein Objekt hast, und auf dieses Objekt aus mehreren Threads zugreifst, teilen sich die Threads die Daten.

Nun Stell Dir vor, auf dem Objekt ist ein (Unicode)String-Property.
Thread 1 befüllt dieses Property gerade aus einer Benutzereingabe. Benutzer tippt langsam, und der Scheduler schiebt zwischendurch ein paar mal den Audioplayer für ein paar Millisekunden rein.
Thread 2 liest nun den Inhalt des Strings.

Der Zustand des Strings ist zu keinem Zeitpunkt wohldefiniert. Es kann durchaus passieren, dass Thread 1 eingefroren wird, nachdem er nur ein enzelnes Byte eines gerade eingetippten Zeichens in den Speicher geschrieben hat, und das zweite Unicode-Byte des Zeichens noch gar nicht im Objekt abgelegt wurde.

Wenn nun während dieser Pause Thread 2 den String liest, dann bekommt er nur halbfertig geschrieben Daten.

Damit so etwas nicht passiert und sichergestellt ist, das ein Thread nur valide Daten bekommt, gibt es methoden zur Thread-Synchronisierung. z.B. Mutexe.
Grob gesagt muss Thread 1 den Speicherbereich des Strings vor dem Schreiben sperren. Jeder der lesen will, muss gucken ob der speicher nicht gesperrt ist. Wenn ja, wird dem Scheduler gesagt: "Pausiere mich, bis der bereich frei ist". Thread 1 kann in Ruhe schreiben und nimmt die Sperre hinterher weg. Dann laufen die anderen lesenden Threads weiter.

Der Trick beim Mutithreading ist also
1.) Seine Aufgaben SO auf mehrere Threads aufzuteilen, dass diese Sperren (Locks) so selten wie möglich genutzt werden müssen und
2.) Herauszufinden, wie viele Threads optimal sind um eine Beschleunigung zu erzielen und wie wenig Threads optimal sind, um nicht zu viele Kontextwechsel zu provozieren.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#14

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:23
Vielleicht kannst Du Dir mal OmniThread anschauen.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#15

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:24
Zitat:
Zwei Threads, die beide Rechnen wollen, auf zwei verschiedene Kerne aufteilen.
Das tue ich ja..
Mein problem ist aber das der RenderThread für die Visualisierung bei ca. 13% gesamter CPU auslastung
einen Kern zu 100% auslastet.

Kann doch nicht einen Thread in 5 Threads aufsplitten um das zu umgehen.
Zumindest habe ich dazu wenn es möglich wäre nicht die erfahrung.

Hmm.. sehe da im moment keine lösung um mein problem zu beheben.

Zitat:
Bitte versteh das jetzt nicht falsch, aber mir scheint Dir fehlen ein bisschen die Grundlagen beim Multithreading.
Keines falls bin ja froh über Ratschläge.
Und ja die fehlen mir etwas.

Zitat:
Seine Aufgaben SO auf mehrere Threads aufzuteilen, dass diese Sperren (Locks) so selten wie möglich genutzt werden müssen und
Ne dumme frage hinterher!
Kann es sein das mein Problem darin besteht das beide Threads über den gleichen Messagehandler verwaltet werden
oder hat das keinen einfluss darauf.

gruss

Geändert von EWeiss (18. Sep 2013 um 19:32 Uhr)
  Mit Zitat antworten Zitat
Robotiker
(Gast)

n/a Beiträge
 
#16

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:39
Mein problem ist aber das der RenderThread für die Visualisierung bei ca. 13% gesamter CPU auslastung einen Kern zu 100% auslastet.
Zitat:
Your CPU meter shows a problem. One core is running at 100 percent, but all the other cores are idle. Your application is CPU-bound, but you are using only a fraction of the computing power of your multicore system. Is there a way to get better performance?
Merkst du was ?

Das zweite Zitat ist von hier
http://msdn.microsoft.com/en-us/library/gg675934.aspx
gibt auch eine C# Version, die finde ich gerade nicht.

Ignorier notfalls den C++ Code, aber lies mal, was da über Techniken zur Parallelisierung steht und versuch halt, das z.B. mit OmniThreads nachzubauen.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#17

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:43
Zitat:
Your CPU meter shows a problem. One core is running at 100 percent, but all the other cores are idle. Your application is CPU-bound, but you are using only a fraction of the computing power of your multicore system. Is there a way to get better performance?
Ja und genau das war mein ziel diesen Beitrag zu schreiben da ich nach einer lösung
für eine bessere Leistung zu erzielen Suche

Parallele Programmierung..
Eine Funktion in mehrere Teile zerlegen wo diese doch zusammen gehört ?
So pauschal kann man das nicht sagen.
Und ich habe sie ja schon in 2 Teile Threads aufgeteilt.
Zitat:
das z.B. mit OmniThreads nachzubauen.
Werd mal schuan ob ich da einen lösungsansatz finden, verwirklichen kann.
Danke.

gruss

Geändert von EWeiss (18. Sep 2013 um 19:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#18

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 19:52
Kann doch nicht einen Thread in 5 Threads aufsplitten um das zu umgehen.
Zumindest habe ich dazu wenn es möglich wäre nicht die erfahrung.
Doch, genau das solltest du versuchen! (Und wenn du jetzt wie der Ochs vorm Berg stehst weist du warum automatische Parallelisierung nicht so der Renner ist)

zum Beispiel habe ich drüben in der EE mal was programmiert was eine lange Zahl mit X multiplizieren musste. Hat natürlich auch 100% CPU Last auf einem Kern gehabt. Dann habe ich das mal auf Papier überprüft und gesehen, dass man das durchaus parallelisieren kann: Man gibt teilt die Zahl einfach in 2 Teile in der Mitte duch. Jeweils ein Thread multipliziert nun eine Hälfte mit X. Was der "linke" herausbekommt ist das Ergebnis was ich wollte. Der Übertrag, den der "rechte" rausbekommt, muss anschließend auf die linke Hälfte draufaddiert werden.

Multiplikation lässt sich also parallelisieren. bei der FFT bin ich mir nicht sicher, aber es könnte schon sein dass das gar nicht geht. Leider gibt es eine Kategorie "einfach parallelisierbar" und eine "quasi nicht parallelisierbar" und nur selten was dazwischen.

@Phoenix: Wenn man hier upvoten könnte, dein Post wäre das wert
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#19

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 20:02
Zitat:
@Phoenix: Wenn man hier upvoten könnte, dein Post wäre das wert
Jo war sehr gut erklärt! danke nochmal dafür

gruss

Geändert von EWeiss (18. Sep 2013 um 20:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#20

AW: Thread auf mehrere Core verteilen

  Alt 18. Sep 2013, 20:25
Dazu müsste man jetzt erstmal wissen, wo genau die Zeit verbraucht wird - also am besten einen Profiler hernehmen.

Zum Beispiel ließen sich die 0..511 Schleifen am Anfang einfach parallelisieren, aber das ist vermutlich fruchtlos weil die eh nicht lange dauern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz