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
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 08:57
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...
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?
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 09:47
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)

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

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

Geändert von EWeiss (20. Sep 2013 um 09:51 Uhr)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 12:47
Also mit anderen Worten, das Rendern selbst im Plugin findet gar nicht mit OpenGL statt? Was ich jetzt nicht verstehe: Wozu verwendest du überhaupt OpenGL?

Ich bin jetzt nicht gerade als Freund von UML bekannt, habe mir jetzt aber trotzdem mal die Mühe gemacht, ein Sequenzdiagramm von deinem Ablauf zu machen, so wie ich ihn verstehe.

So wie ich das sehe, ist OpenGL bei dir völlig redundant, da du nur 1:1 die Daten auf den Bildschirm ausgibst, die du vorher schon auf der CPU berechnet und gezeichnet hast. Du blittest sogar das gleiche zwei mal, indem du erst mal mit der GDI die Visualisierung auf das OpenGL-DC zeichnest, und dann noch mal mit OpenGL selbst als texturierter Quad.

Die ganze Arbeit macht bei dir die CPU, durch die Verwendung der GPU erhöhst du hier nur den Overhead und machst das ganze langsamer.

Sorry, wenn ich es missverstanden habe, aber so erschließt es sich aus deinem letzten Beitrag.
Angehängte Grafiken
Dateityp: png visbuf.png (37,2 KB, 32x aufgerufen)

Geändert von Namenloser (20. Sep 2013 um 12:51 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 13:28
Zitat:
Also mit anderen Worten, das Rendern selbst im Plugin findet gar nicht mit OpenGL statt?
Ja und nein.

Zitat:
Du blittest sogar das gleiche zwei mal, indem du erst mal mit der GDI die Visualisierung auf das OpenGL-DC zeichnest, und dann noch mal mit OpenGL selbst als texturierter Quad.
Ja gerade deshalb um die CPU zu schonen.
Ob ich nun den Viewport 512x384 also gestretcht auf die weite von 1920x1200 render
oder einen im format 1:1 macht schon einen riesen unterschied.

Das gestretche Format wird dann natürlich auch in OGL übernommen.
Das ist bedingt durch die Plugins selbst weil diese eigentlich für ein Bildformat von 512x512 ausgelegt sind.
Die Leute wollen aber VollBild.

Zitat:
Die ganze Arbeit macht bei dir die CPU, durch die Verwendung der GPU erhöhst du hier nur den Overhead und machst das ganze langsamer.
Bedingt vielleicht..
Ist auch eine frage der Ansicht ob ich nun einen schriftzug in OGL Render oder einen in GDI macht doch schon einen recht großen Unterschied.
Zumal über BitBlt dieser dann auch noch in die Renderscene mit eingebunden wird (GDI)und das will ich nicht.
Da dies bei OGL-Plugins unansehnlich aussieht.

Zwischen Bass.dll und Plugin käme dann noch mein Wrapper und darum gehts

gruss
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 13:44
Zitat:
Du blittest sogar das gleiche zwei mal, indem du erst mal mit der GDI die Visualisierung auf das OpenGL-DC zeichnest, und dann noch mal mit OpenGL selbst als texturierter Quad.
Drüber war eine falsche Aussage!
Nein Blite nur dann wenn GDI verwendet wird ansonsten über texturierte Quads
Natürlich trotzdem gestretcht abhängig vom Viewport.

Bin jetzt soweit das es funktioniert.

gruss
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 13:45
Ja gerade deshalb um die CPU zu schonen.
Ob ich nun den Viewport 512x384 also gestretcht auf die weite von 1920x1200 render
oder einen im format 1:1 macht schon einen riesen unterschied.

Das gestretche Format wird dann natürlich auch in OGL übernommen.
Das ist bedingt durch die Plugins selbst weil diese eigentlich für ein Bildformat von 512x512 ausgelegt sind.
Die Leute wollen aber VollBild.
Ja aber StretchBlt wird doch auf der CPU ausgeführt! Also so bringt das einfach gar nichts; dein Ziel, die CPU zu entlasten, verfehlst du komplett.

Wenn dann müsstest du dir das StretchBlt schon sparen, dann würdest du wenigstens das Skalieren von der CPU auf die GPU verlagern. Aber selbst dann würde ich noch bezweifeln, dass das den Overhead von OpenGL rechtfertigt, denn: Die Bitmap-Daten werden, bevor sie an die GPU gelangen, mehrfach im Speicher herumkopiert, und dann müssen sie auch noch über den PCI-Port wandern, der ein berüchtigter Flaschenhals ist.

Faustregel: Generell ist es immer extrem langsam, irgendwas von der CPU auf die GPU zu transferieren oder umgekehrt.

Ich würde mit dir wetten, dass, wenn du OpenGL komplett rausschmeißt, du ein schnelleres Programm kriegst. Oder zumindest eines, das leichter zu warten ist und gleich schnell ist.

Und danach könntest du vielleicht über Multithreading nachdenken. Aber auch Multithreading ist, ebenso wie OpenGL, kein Silver Bullet.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 13:52
Zitat:
Ja aber StretchBlt wird doch auf der CPU ausgeführt! Also so bringt das einfach gar nichts; dein Ziel, die CPU zu entlasten, verfehlst du komplett.
Nein habe es doch über deinen Beitrag berichtigt.
Und Multithreading funktioniert auch mit OpenGL

gruss
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#8

AW: Thread auf mehrere Core verteilen

  Alt 20. Sep 2013, 14:01
Zitat:
Ja aber StretchBlt wird doch auf der CPU ausgeführt! Also so bringt das einfach gar nichts; dein Ziel, die CPU zu entlasten, verfehlst du komplett.
Nein habe es doch über deinen Beitrag berichtigt.
Aber das Plugin rendert immer in VisBuf, oder? Ich weiß nicht so recht, was ich unter deinem „Ja und Nein“ zu verstehen habe. Zumindest steht es so im Code, den du gezeigt hast.

Hast du denn mal gemessen, ob es mit OpenGL wirklich schneller ist als nur mit der GDI?
Und Multithreading funktioniert auch mit OpenGL
Ja, aber spaßig ist es nicht gerade. Bevor ich mich da ins Gefecht stürze, würde ich mir lieber überlegen, ob das wirklich ein guter Ansatz ist.
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz