Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Thread auf mehrere Core verteilen (https://www.delphipraxis.net/176642-thread-auf-mehrere-core-verteilen.html)

EWeiss 18. Sep 2013 14:58

Thread auf mehrere Core verteilen
 
Vielleicht ist der Titel etwas blöd gewählt.

Ist es möglich in Delphi einen Thread über 2 Core laufen zu lassen?
Wenn ich nur einen verwende lastet die Anwendung aus wenn von einem Kern 100% verwendet wird.

Keine Ahnung ob sowas überhaupt möglich ist eventuell MultiThreads?
Aber wie bei nur einer Funktion (RenderThread)

Vielleicht ist die Frage aber auch einfach nur bescheuert ;)

gruss

Uwe Raabe 18. Sep 2013 15:02

AW: Thread auf mehrere Core verteilen
 
Ein Thread läuft immer nur auf einem Kern. Bei einer hyper-threading fähigen CPU ist das dann ein virtueller Kern. Wenn du mehrere Kerne nutzen möchtest, musst du die Aufgabe in mehrere Teile aufsplitten und in separaten Threads laufen lassen. Die Schwierigkeit dabei ist halt oft das Aufsplitten.

Meflin 18. Sep 2013 15:02

AW: Thread auf mehrere Core verteilen
 
Ein Thread kann nicht gleichzeitig auf mehreren Cores laufen. Das ergibt auch einfach keinen Sinn. Wenn du mehrere Cores gleichzeitig auslasten willst, musst du deine Arbeit eben auf entsprechend viele Threads aufteilen.

BUG 18. Sep 2013 15:08

AW: Thread auf mehrere Core verteilen
 
Du kannst deinen Thread nicht automatisch auf mehreren Kernen ausführen lassen. Das heißt, du musst dir Gedanken machen ob und wie man dein Problem parallelisieren kann.
Das hängt aber sehr davon ab, was deine Funktion überhaupt macht und wie die Ressourcen aussehen, auf die da zugegriffen wird. Womöglich musst du einiges anfassen, um überhaupt parallelisieren zu können.

EWeiss 18. Sep 2013 15:29

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von BUG (Beitrag 1228948)
Du kannst deinen Thread nicht automatisch auf mehreren Kernen ausführen lassen. Das heißt, du musst dir Gedanken machen ob und wie man dein Problem parallelisieren kann.
Das hängt aber sehr davon ab, was deine Funktion überhaupt macht und wie die Ressourcen aussehen, auf die da zugegriffen wird. Womöglich musst du einiges anfassen, um überhaupt parallelisieren zu können.

Ich sehe schon das hört sich wirklich schwierig an.
Die Function tut nichts anderes als FFT Daten zu analysieren, visualisiert auszugeben.
Das problem dabei es läuft über mehrere ebenen.

Anwendung, DLL als wrapper zu einer anderen DLL.. Sonique Plugins als Beispiel.
Diese Visualisieren dann die FFT Daten die übergeben werden.
Das problem ist dabei das diese eigentlich nur für Fenster größen 512x512 ausgelegt sind was natürlich
bei einem VollBild von 1920x1200 als bsp. immense probleme verursacht.

Hab das jetzt so umgestellt das man im Vollbild gehen kann in dem ich den Usern einen Viewport zur verfügung stelle
so das die Visualisierungen in einem Vollbild wie schon genannt in unterschiedlichen Viewports gerendert werden kann (512x348 bsp.)
Aber ganz komme ich immer noch nicht hin was die auslastung des einen Kern's angeht.

Hab zwar nur max 25% CPU auslastung bringt mir aber nichts wenn ein Kern mit voller last läuft.
Die Anwendung hängt dann unweigerlich.

gruss

BUG 18. Sep 2013 16:22

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1228957)
Die Function tut nichts anderes als FFT Daten zu analysieren, visualisiert auszugeben.

Ich nehme mal an, dass die FFT das Arbeitsintensive ist. Man könnte eine parallele Implementierung ausprobieren (scheint Bei Google suchenviel Material dazu geben).
Andererseits ist die Frage, ob du wirklich alle Frequenzen pixelgenau darstellen musst. Eventuell könntest du Zwischenergebnisse interpolieren.

EWeiss 18. Sep 2013 16:35

AW: Thread auf mehrere Core verteilen
 
Zitat:

Andererseits ist die Frage, ob du wirklich alle Frequenzen pixelgenau darstellen musst.
Habe ich ja keinen Einfluss drauf da das zeichnen aus den Plugins heraus geschieht.
Etwas habe ich es ja schon entspannen können aufgrund der Viewports.
Die Auslastung ist von einigen Faktoren abhängig Rendertiming größe des Viewport und ob OGL oder GDI verwendet wird.

Hab gelesen das es in C++ / Net möglich sein soll Multithreads zu erstellen.
Bei Delphi sagt man das es nicht so einfach funktionieren soll. (ohne extremen Aufwand)

Na ja schade eigentlich.
Muss es dann wohl so belassen, wieder mal na grenzen gestoßen.. ;)

Zitat:

Man könnte eine parallele Implementierung ausprobieren
Gibts nicht viel möglichkeiten da diese vom stream über die Bass.dll zurückgegeben werden.

gruss

Uwe Raabe 18. Sep 2013 16:49

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1228971)
Hab gelesen das es in C++ / Net möglich sein soll Multithreads zu erstellen.
Bei Delphi sagt man das es nicht so einfach funktionieren soll. (ohne extremen Aufwand)

Der Aufwand ist in beiden Umgebungen vergleichbar. Einen zusätzlichen Thread zu erstellen ist in Delphi mindestens so einfach wie in einer anderen Umgebung. Die Probleme liegen eher darin, einen Algorithmus zu verwenden, der nicht nur threadsicher ist, sondern auch praktikabel skaliert.

Wenn du lediglich das Hängen der Anwendung vermeiden willst, reicht es ja schon, wenn du die Berechnung insgesamt in einen eigenen Thread verlagerst.

EWeiss 18. Sep 2013 17:30

AW: Thread auf mehrere Core verteilen
 
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.

gruss

Robotiker 18. Sep 2013 17:55

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1228973)
Der Aufwand ist in beiden Umgebungen vergleichbar. Einen zusätzlichen Thread zu erstellen ist in Delphi mindestens so einfach .

Jein. Für normale von Hand programmierte Threads ist das richtig.

Zitat:

Zitat von EWeiss (Beitrag 1228984)
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.

Moderne Compiler (CLang, Intel Fortran oder C++, MS VC++) können sowas in der Art. Entweder über Autoparallelisierung
http://msdn.microsoft.com/en-us/library/hh872235.aspx
über OpenMP
http://openmp.org/wp/
oder über Bibliotheken
https://www.threadingbuildingblocks.org/home
http://msdn.microsoft.com/de-de/libr.../dd492418.aspx

Das findet aber alles außerhalb der Pascal Welt statt.

EWeiss 18. Sep 2013 18:10

AW: Thread auf mehrere Core verteilen
 
Zitat:

Das findet aber alles außerhalb der Pascal Welt statt.
Danke!

Ja leider..

gruss

jfheins 18. Sep 2013 18:16

AW: Thread auf mehrere Core verteilen
 
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.

Phoenix 18. Sep 2013 18:22

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1228984)
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.

Union 18. Sep 2013 18:23

AW: Thread auf mehrere Core verteilen
 
Vielleicht kannst Du Dir mal OmniThread anschauen.

EWeiss 18. Sep 2013 18:24

AW: Thread auf mehrere Core verteilen
 
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

Robotiker 18. Sep 2013 18:39

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1228992)
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.

EWeiss 18. Sep 2013 18:43

AW: Thread auf mehrere Core verteilen
 
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

jfheins 18. Sep 2013 18:52

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1228992)
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 ;-)

EWeiss 18. Sep 2013 19:02

AW: Thread auf mehrere Core verteilen
 
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

jfheins 18. Sep 2013 19:25

AW: Thread auf mehrere Core verteilen
 
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.

EWeiss 18. Sep 2013 19:49

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von jfheins (Beitrag 1229008)
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.

Die meiste power nimmt das rendern in der externen DLL(Plugin) in Anspruch..
Denke mal das ich da nicht viel machen kann.
Na ja dann müssen sich die User mit den verfügbaren Einstellungen begnügen und diese so anpassen
das ihr system das Rendern in erträglichen Ausmaß verkraften.

gruss

Whookie 19. Sep 2013 17:51

AW: Thread auf mehrere Core verteilen
 
Vielleicht verstehe ich das Problem nicht ganz richtig, aber wenn die Auslastung nur durch ständig wiederholtes Zeichnen entsteht (so etwas wie eine Live-Anzeige einer FFT eines Audiospektrums), dann könnte man auch einfach die Ausgabe "seltener" durchführen (also das Rendern nur alle 40ms bis 60ms aufrufen).

EWeiss 19. Sep 2013 17:55

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von Whookie (Beitrag 1229140)
Vielleicht verstehe ich das Problem nicht ganz richtig, aber wenn die Auslastung nur durch ständig wiederholtes Zeichnen entsteht (so etwas wie eine Live-Anzeige einer FFT eines Audiospektrums), dann könnte man auch einfach die Ausgabe "seltener" durchführen (also das Rendern nur alle 40ms bis 60ms aufrufen).

Auf keinen fall ;)
Schließlich will ich nicht mit 10 FPS rendern sondern in Realzeit.
Die Live Anzeige wie du es nennst würde dann nicht synchron (Beat) zur Musik laufen.

gruss

OlafSt 19. Sep 2013 18:14

AW: Thread auf mehrere Core verteilen
 
Wenn die Anzeige 10x die Sekunde neu gezeichnet wird, dann ist das schon verdammt nah dran. Und das ist ein Neuzeichnen alle 100ms. Ich denke, 20fps würden mehr als dicke reichen, das sind 50ms zwischen den Redraws.

EWeiss 19. Sep 2013 18:24

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von OlafSt (Beitrag 1229146)
Wenn die Anzeige 10x die Sekunde neu gezeichnet wird, dann ist das schon verdammt nah dran. Und das ist ein Neuzeichnen alle 100ms. Ich denke, 20fps würden mehr als dicke reichen, das sind 50ms zwischen den Redraws.

Nö das reicht nicht bedenke um so höher die Auflösung desto geringer die FPS..
Das mag bei einer Auflösung von 320x240 gehen aber nicht bei 1920x1200 oder drüber
Es bringt mir nichts wenn ich auf grund irgendwelcher einsparungen letztendlich mit dem Beat hinterher hinke..
Alles schon versucht.

gruss

Namenloser 19. Sep 2013 19:23

AW: Thread auf mehrere Core verteilen
 
Was genau zeichnest du da eigentlich und wie? Wenn du es mit DirectX oder OpenGL machst, sollte die Auflösung doch fast keine Rolle spielen...

EWeiss 19. Sep 2013 19:34

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von NamenLozer (Beitrag 1229158)
Was genau zeichnest du da eigentlich und wie? Wenn du es mit DirectX oder OpenGL machst, sollte die Auflösung doch fast keine Rolle spielen...

Mit was man zeichnet spielt keine rolle bei beiden DX und OGL ändert sich die FPS abhängig von der Fenster größe.

Siehst du doch bei spielen wenn man hier die Auflösung ändert.
Aber wie im Beitrag schon geschrieben geht es mir nicht um die FPS sondern darum
das ein Core mit Volllast fährt obwohl die CPU ansich nicht ausgelastet ist.

Arbeite dran ;)

gruss

Namenloser 19. Sep 2013 20:03

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1229163)
Zitat:

Zitat von NamenLozer (Beitrag 1229158)
Was genau zeichnest du da eigentlich und wie? Wenn du es mit DirectX oder OpenGL machst, sollte die Auflösung doch fast keine Rolle spielen...

Mit was man zeichnet spielt keine rolle bei beiden DX und OGL ändert sich die FPS abhängig von der Fenster größe.

Siehst du doch bei spielen wenn man hier die Auflösung ändert.

Aber nur bei graphisch sehr aufwändigen Spielen, ansonsten sind meist mehr FPS möglich als der Bildschirm darstellen kann. Dass das Rendern deines wie auch immer aussehenden Frequenzhistograms so aufwändig ist, dass es (auf der GPU) länger dauert als die FFT (auf der CPU), kann ich mir irgendwie kaum vorstellen, es sei denn, da ist irgendwas sehr ineffizient gelöst. Aber es ist halt schwer zu sagen, wenn man so wenig konkretes weiß. Wenigstens ein Screenshot um mal grob einen Eindruck zu bekommen, worum es eigentlich geht, wäre hilfreich...

Falls wirklich das Rendern auf der GPU der Flaschenhals ist, bringt dir jedenfalls auch Multithreading nichts.

EWeiss 19. Sep 2013 20:22

AW: Thread auf mehrere Core verteilen
 
Die GPU hat gerade mal 9% (vom gesamten System natürlich) die probleme macht die CPU ein Kern!

Weiss nicht was dir ein Bild jetzt sagt habe es aber mal angehängt.
Habe es in einem Archiv gepackt weil es sonst hier im Forum verkleinert wird.

gruss

glotzer 19. Sep 2013 21:41

AW: Thread auf mehrere Core verteilen
 
Liste der Anhänge anzeigen (Anzahl: 2)
für alle die wie ich darüber genervt sind/waren das archiv erst entpacken zu müssen... :

EWeiss 19. Sep 2013 21:49

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von glotzer (Beitrag 1229189)
für alle die wie ich darüber genervt sind/waren das Archiv erst entpacken zu müssen... :

Du Spassvogel! :)

Dir ist wohl klar das du nun die relativen Dinge um die es geht nun nicht mehr siehst?
Es hatte schon einen grund das ich es in einem archiv gepackt habe.
Die Auslastung der resourcen GPU/CPU usw.. kann man auf deinen Shot nicht mehr erkennen.

gruss

glotzer 19. Sep 2013 21:55

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1229190)
Dir ist wohl klar das du nun die relativen Dinge um die es geht nun nicht mehr siehst?

Sind doch bestens zu lesen ;)

Uwe Raabe 19. Sep 2013 22:02

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von glotzer (Beitrag 1229192)
Sind doch bestens zu lesen ;)

...wenn man drauf klickt...

EWeiss 19. Sep 2013 22:37

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1229194)
Zitat:

Zitat von glotzer (Beitrag 1229192)
Sind doch bestens zu lesen ;)

...wenn man drauf klickt...

logisch nur vorher hatte er es nicht ausgeschnitten.. und extra hochgeladen.
Aber egal hab keine zeit zum spielen. ;)

Ok Danke trotzdem hab das Archiv gelöscht.

gruss

Mikkey 20. Sep 2013 07:34

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1229201)
Aber egal hab keine zeit zum spielen. ;)

Um auf das Eingangsproblem zurückzukommen...

ich sehe hier eine relativ einfache Möglichkeit zur Parallelisierung. Du solltest einen Kern(=Thread) den Frame rendern lassen und einen anderen Kern bereits den nächsten.

Wenn Du so die Arbeit auf 4 Kerne verteilst, hat jeder Kern die vierfache Zeit für seine Arbeit. Du musst natürlich die Soundausgabe soweit verzögern, dass sie zeitgleich mit der Anzeige kommt.

Das ganze erfordert natürlich einen ziemlichen Verwaltungsaufwand.

Mit anderen Worten:
Die Kerne werkeln gleichzeitig an vier aufeinanderfolgenden Frames. Sie stellen ihr Ergebnis in eine kurze Warteschlange, die von der Grafikausgabe aufgenommen und auf den Bildschirm gebracht wird. Kern1 bearbeitet also die Frames 1,5,9..., Kern2 2,6,10..., Kern 3 3,7,11... und Kern 4 4,8,12...

EWeiss 20. Sep 2013 08:20

AW: Thread auf mehrere Core verteilen
 
Danke für die Informationen.
Ich habe es mal getestet nur mit einem zusätzlichen Thread.
So wie es aussieht scheint es zu funktionieren werden nun alle Kerne vergleichsweise ausgeglichen verwendet.

Allerdings hab ich nun schwierigkeiten beim verändern der Fenstergröße.
OGL ist da ziemlich pingelig wenn der Contex incl. GL-Befehle nicht ausschließlich aus dem Thread
heraus behandlet werden.
Fenster resitz.. crash ;)

Muss da wohl noch einiges optimieren.

gruss

Phoenix 20. Sep 2013 08:28

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1229235)
Allerdings hab ich nun schwierigkeiten beim verändern der Fenstergröße.
OGL ist da ziemlich pingelig wenn der Contex incl. GL-Befehle nicht ausschließlich aus dem Thread
heraus behandlet werden.
Fenster resitz.. crash ;)

Das ist der Punkt mit der Synchronisierung.
Da versucht dann ein Thread (z.b. Berechnung) was zu verändern, wo in dem Moment ein anderer Thread (z.b. Anzeige) darauf zugreift. Das knallt.
Du musst also also Übergabepunkte zwischen den Threads synchronisieren (z.B. Mutex drumrum packen).

Willkommen in der schweren, steinigen Welt des Multithreadings ;-)

EWeiss 20. Sep 2013 08:36

AW: Thread auf mehrere Core verteilen
 
Zitat:

Willkommen in der schweren, steinigen Welt des Multithreadings
Danke auch Herzlichst :-D
Jetzt mal unabhängig von den Kernen OGL hat ein grundsätliches problem mit Threads
Wenn man dann noch bedenkt das die Plugins ein mismatch aus GDI/OGL sind kommt man letztendlich
zum schluss das die Schnittstelle nicht gerade durchdacht ist.

Ok.. Das ist ne andere sache wird langsam OT ;)

gruss

Namenloser 20. Sep 2013 08:57

AW: Thread auf mehrere Core verteilen
 
Zitat:

Zitat von EWeiss (Beitrag 1229170)
Weiss nicht was dir ein Bild jetzt sagt habe es aber mal angehängt.

Weil Bilder weniger missverständlich als Beschreibungen sind. Ist mir z.B. schon oft so gegangen, dass ich Leuten versucht habe, bei irgendwelchen Computerproblemen zu helfen und sie stundenlang per Messenger ausgefragt habe und wir völlig aneinander vorbeigeredet haben, und nach einem Screenshot war sofort klar, was Sache ist...
Zitat:

Zitat von EWeiss (Beitrag 1229170)
Die GPU hat gerade mal 9% (vom gesamten System natürlich) die probleme macht die CPU ein Kern!

Und das macht mich stutzig. Also wenn du sagst, dass das Rendern bei größerer Auflösung langsam wird, dann würde das bedeuten, dass die GPU der Flaschenhals ist, weil diese sich ja um das Rendern kümmert. Der CPU ist es ja egal, wie groß die Ausgabe der GPU ist, denn auf der CPU laufen unabhängig von der Auflösung immer die gleichen Befehle.

Aber da die GPU nur zu 14% (laut deinem Screenshot) ausgelastet ist, kann das nicht das Problem sein. Jetzt ist die Frage, was macht dein Programm bei höheren Auflösungen auf der CPU anders? Und welche Stationen durchläuft bei dir ein Frame genau, bevor es auf dem Bildschirm ausgegeben wird? Läuft das alles über OpenGL direkt? Oder – Gott bewahre – liest du etwa den OpenGL-Framebuffer mit glReadPixels aus, damit du das Gezeichnete mit der GDI weiterverwenden kannst?

EWeiss 20. Sep 2013 09:47

AW: Thread auf mehrere Core verteilen
 
Ich erstelle einen GDI-VideoBuffer(VisBuf) abhängig vom Viewport = bsp. 512x384 außerhalb des Threads.
Die Visualisierung wird dann also in VollBild 1920x1200 auf den Viewport 512x384 gestretcht.
Das schont CPU resourcen.

Delphi-Quellcode:
  FillChar(BmpInfo, SizeOf(BITMAPINFO), 0);
  BmpInfo.bmiHeader.biSize    := SizeOf(BITMAPINFOHEADER);
  BmpInfo.bmiHeader.biWidth   := StretchWidth;
  BmpInfo.bmiHeader.biHeight  := -StretchHeight;
  BmpInfo.bmiHeader.biPlanes  := 1;
  BmpInfo.bmiHeader.biBitCount := 32;

  VisBmp := CreateDIBSection(0, BmpInfo, DIB_RGB_COLORS, VisBuf, 0, 0);
Dann wird der Record VisData mit den Wave/FFT Daten gefüttert
und anschließend im Plugin selbst gerendert wo ich keinen Einfluss drauf habe
Delphi-Quellcode:
        if (not VisInfo^.VisPointer^.Render(VisInfo^.VisBuf, StretchWidth,
          StretchHeight, StretchWidth, @VisData)) then
anschließend hole ich mir das DC vom OpenGL Contex (RenderWindow)

Delphi-Quellcode:
DC := GetDc(ParentHandle);


Danach verwende ich StretchBlt um die Daten auf das DC vom Source VisDC zu zeichnen
Delphi-Quellcode:
        if (not StretchBlt(DC, VisInfo^.x, VisInfo^.y, VisInfo^.w, VisInfo^.h, VisInfo^.VisDC, 0,
          0, StretchWidth, StretchHeight, SRCCOPY)) then
Anschließend wird der inhalt vom VisBuf in eine OGL-Texture kopiert

Delphi-Quellcode:
       
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, StretchWidth, StretchHeight, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, VisInfo^.VisBuf);
Der rest sind noch ein paar OGL sachen
Delphi-Quellcode:
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
...
glFlush();
SwapBuffers(glDC);
Das wars dann.

Nach meiner änderung von Timer auf Thread geht es jetzt soweit und die Kerne werden
gleichmäßig ausgelastet.
Wenn aber nun aus der Anwendung heraus die resitz Message geschickt wird die außerhalb des threads läuft

Delphi-Quellcode:
Result := BASS_SONIQUEVIS_Resize(Param^.VisHandle, Left, Top, Width, Height);


dann kracht es gewaltig in irgendeiner OGL .dll

so sieht es im moment aus.
Zitat:

liest du etwa den OpenGL-Framebuffer mit glReadPixels aus
Nein die Pixels werden in Rechtecke zerlegt aus der glTexImage2D Texture

Delphi-Quellcode:
        glColor4f(1, 1, 1, 1);
            glEnable(GL_TEXTURE_2D);
            glBegin(GL_QUADS);
              glTexCoord2d(0.0, 0.0);
              glVertex2f( 0.0, 0.0);
              glTexCoord2d(0.0, 1.0);
              glVertex2f( 0.0, LastHeight);
              glTexCoord2d(1.0, 1.0);
              glVertex2f(LastWidth, LastHeight);
              glTexCoord2d(1.0, 0.0);
              glVertex2f(LastWidth, 0.0);
        glEnd();

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:12 Uhr.
Seite 1 von 2  1 2      

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