Frage bzgl MM Multiplikation mit OpenGL



  • Hi Leute,

    Ich bin absoluter ANfänger in der Gegen rund um OpenGL und muss eine Präsentation vorbereiten über verschiedene APIs. Daher dachte ich eine Matrixmultiplikation zu implementieren für verschiedene APIs, wie auf CPU, OpenGL, OpenCL, Cuda etc.

    Ich habe schon ne Weile für OpenGL gesucht aber nichts sinnvolles gefunden...
    Daher meine Frage: Ist es überhaupt möglich eine stinknormale M=MxM Multiplikation mit OpenGL zu realiseren, also so dass die Multiplikation auf der GPU stattfindet?

    Ich möchte keinerlei Spielchen drum herum haben, wie Fenster/geometrische Figuren etc., sondern nur die MxM auf der GPU... und davon will ich halt die Zeit messen

    DIe Matrix soll 1000x1000 oder größer sein. Gibt da möglichst einfach Ansätze, wie man dies einfach und nachvollziehbar implementieren kann? Oder ob sowas überhaupt möglich ist, ohne das auf geometrische Körper abbilden zu müssen?

    Danke für alle Hinweise
    Alex



  • Möglich? Ja
    Sinnvoll? Eher weniger

    OpenGL und OpenCL bzw. CUDA sind für völlig verschiedene Anwendungsbereiche gedacht und stehen nicht in Konkurrenz zueinander, sondern ergänzen sich vielmehr. Wenn du etwas vergleichen willst, dann vergleiche OpenCL und CUDA. Wenn du wirklich OpenGL in diesen Vergleich pressen willst, dann solltest du wohl einen Blick in Richtung der mit OpenGL 4.3 dazugekommenen Compute Shader werfen. Aber auch dabei dann bitte immer den unterschiedlichen Kontext im Auge behalten. Für reine lineare Algebra wird jedenfalls niemand, der recht bei Sinnen ist, heutzutage zu OpenGL greifen; wenn du sowas in deinen Vergleich einbeziehen willst, dann höchstens um zu illustrieren, wie man die Grafikpipeline zweckentfremden könnte, wenn es OpenCL bzw. CUDA usw. nicht gäbe...



  • Wenn der Werte- und Definitionsbereich <= 2^32 sind kannst du einen einfachen Shader schreiben, ein 1000*1000 Pixel großes Bild rendern und 2 1000*1000 Texturen für die Matrizen benutzen. Ausgabe ist dann halt das Bild und für die Zeitmessung kannst du die Framerate nehmen. Ansonsten halt das Kopieren der Texturen und das Zurückkopieren des Bildes mit rein rechnen.
    Beachte, dass die Berechnung mit floats im Shader deutlich schneller geht als mit Integern. Ich bin mir nicht ganz sicher, ob du den Alpha-Wert ausgelesen kriegst, möglicherweise verkleinert sich da der Wertebereich auf 2^24.



  • Danke erstmal für die Antworten.. Ich denke bzgl meines VOrtrag habe ich mich nun eher auf CUDA konzentriert. Dort habe ich nun auch kleine Programme ans Laufen gebracht. Nun aber eine andere Frage:

    Kann man irgendwelche "belegen"/"zeigen", dass tatsächlich auf der GPU gerechnet wird? Habe auch das Tool CapsViewer gefunden mit der GPU Load ANzeige (%). Die ANzaige bewege sich irgendwie zwischen 0 und 2 %.

    Ist mein Programm (Vektoraddition mit der Länge mit Array von 25000 Stellen) zu "primitiv" so dass man gar keine Änderung sehen kann? Selbst wenn ich 2 For Schleifen die "quasi" nichts tun in den Kernel schreibe und die laufvariable auf >1000000 setze gibts keine Änderung. Hat jemand dabei eine, wie man dies erklären kann?

    Ich habe mal irgendwo im Inet gelesen, dass CUDA automatisch auf die CPU wechselt, wenn was im Hintergrund nicht möglich erscheint... Kann man sowas (de)aktivieren?



  • Balex123 schrieb:

    Ich habe mal irgendwo im Inet gelesen, dass CUDA automatisch auf die CPU wechselt, wenn was im Hintergrund nicht möglich erscheint... Kann man sowas (de)aktivieren?

    Das ist Bullshit, CUDA läuft auf der GPU oder gar nicht. Als man noch nicht wirklich gut auf der GPU debuggen konnte, gab es mal die Möglichkeit, CUDA Code für die CPU zu kompilieren, um dort debuggen zu können; das wird mittlerweile afaik aber nichtmal mehr supported. Ich würde eher mal vermuten, dass dieses Tool da unbrauchbar ist; ich würd z.B. zu Nsight raten. Alternativ könntest du das Gleiche (mit wesentlich mehr Elementen, wie wärs mit z.B. 1M) auch einfach mal auf der CPU machen und demonstrieren, wieviel länger es dort dauert. Als eindrucksvollere Illustration könntest du z.B. parallel eine GPU-lastige Grafikanwendung laufen lassen, dann könnte man evtl. sehen, dass die fps dort einbrechen, wenn das CUDA Teil läuft, aber einigermaßen stabil bleiben, wenn das CPU Teil läuft...



  • Du musst aufpassen, dass dein Programm (das was auf der GPU laufen soll) nicht wegoptimiert wird.



  • cooky451 schrieb:

    Du musst aufpassen, dass dein Programm (das was auf der GPU laufen soll) nicht wegoptimiert wird.

    Hi, danke für den Hinweis ... Gibt es irgendein flag was man beim aufruf von nvcc bzw. gcc angeben kann, damit keine optimierung stattfindet?

    Sry für so eine frage, ich bin normalerweise kein C/C++ freund,



  • GCC ist kein Problem, es geht ja um das Programm was dann auf der Grafikkarte läuft. Google einfach mal nach "nvcc disable optimization"



  • Der Sinn davon, hier Compileroptmierungen abzuschalten, will sich mir nicht wirklich offenbaren...

    EDIT: Achso es ging um die leere Schleife, das ist aber auch nicht unbedingt ein sinnvolles Beispiel... 😉



  • Joa, letztlich kannst du auch einfach viele Zufallszahlen generieren und dann den User fragen welche Zahl er (beim Ergebnis) angezeigt bekommen will, dann kannste sicher sein dass da nichts weg optimiert wird.


Anmelden zum Antworten