Hallo,
ich möchte gerne etwas in das Thema Berechnungen auf der GPU reinkommen
das Ganze in C++.
Ich stelle mir daher gerade ganz naiv ein paar grundsätzliche Fragen
dazu teilweise erstmal ganz unabhängig vom Usecase oder der
Parallelisierung.
# Steigt man besser per OpenCL, CUDA, oder Thrust library, etc ein und
welches macht nachhaltig Sinn? OpenCL scheint unabhängiger zu sein und
Thrust library wird auch oft angeführt und soll der STL ähnlich sein.
# Und erstmal ganz naiv, kann man auf einer GPU grundsätzlich den
gleichen Code ausführen wie auf einer CPU ? Wäre es möglich ein normales
in C++ geschriebenes Programm auf einem "GPU Kern" auszuführen bzw kann
man zB eine normale Funktion zu einer machen die auf der GPU laufen
soll?
# Liegen Variablen die durch die GPU verarbeitet werden immer auch auf
dem GPU Speicher oder kann es auch Zugriffe auf den CPU-RAM geben?
# Wenn tausende GPU Berechnungen auf Grundlage gleicher Daten parallel
stattfinden kann der GPU-RAM sicher nicht für jede Berechnung die Daten
einzelnd vorhalten dafür wäre sicher der GPU-RAM zu klein. Daher kann
man (wie normal) parallel auf Daten lesend zugreifen? Wenn zB ein Array
für die Berechnungen genutzt werden würde, wäre es dann möglich das
tausende der "GPU Kerne" alle lesend darauf zugreifen können oder wie
ist der normale Umgang damit?
Grüße
Du solltest dich vielleicht zuerst mal mit den gravierenden
unterschieden zwischen CPU und GPU beschäftigen.
Der eine ist ein Generalist der fast alles kann der andere ein absoluter
Spezialist der nur sehr wenig kann, dass dafür aber sehr schnell.
Wenn du das halbwegs verstanden hast wirst du schnell merken das
Berechnungen auf der GPU nur dann Sinn machen wenn du ganz bestimmte
Datenmuster und Berechnungsalgorithmen hast.
So einfach irgendein Programmcode auf die GPU zu bringen scheitert z.b:
schon daran das du von dortaus nicht einfach mit den OS kommunizieren
kannst und z.B. einen API-Aufruf durchführen usw. Für den Transport der
Daten von/zu Extern bzw. auch dem (Betriebssystem)CPU-RAM zur GPU bist
du auch immer auf die Zusammenarbeit mit der CPU(bzw. dem durch diese
gesteuerten DMA-Controller) angewiesen usw.
https://de.wikipedia.org/wiki/Grafikprozessorhttps://de.wikipedia.org/wiki/General_Purpose_Computation_on_Graphics_Processing_Unithttps://de.wikipedia.org/wiki/Flynnsche_Klassifikation#SIMD_.28Single_Instruction.2C_Multiple_Data.29
A. Froh schrieb:> # Steigt man besser per OpenCL, CUDA, oder Thrust library, etc ein und> welches macht nachhaltig Sinn? OpenCL scheint unabhängiger zu sein und> Thrust library wird auch oft angeführt und soll der STL ähnlich sein.
Eindeutig OpenCL, das ist nicht auf einen Hersteller beschrängt, es ist
weit verbreitet, kann mit OpanGL oder Vulkan combiniert werden, etc.
> # Und erstmal ganz naiv, kann man auf einer GPU grundsätzlich den> gleichen Code ausführen wie auf einer CPU ? Wäre es möglich ein normales> in C++ geschriebenes Programm auf einem "GPU Kern" auszuführen bzw kann> man zB eine normale Funktion zu einer machen die auf der GPU laufen> soll?
Jein, grundsätzlich wären compiler backends für GPUs machbar, aber es
ist nicht wirklich sinvoll und jede Grafigkarte bräuchte ein neues
backend, und der code wäre darauf langsamer, etc. OpenCL ist aber sehr C
ähnlich und besser für GPUs und deren Paralellisierung geeignet.
> # Liegen Variablen die durch die GPU verarbeitet werden immer auch auf> dem GPU Speicher oder kann es auch Zugriffe auf den CPU-RAM geben?
Solange du den Treiber nicht schreiben musst, und du keine verwendung
von low level Interfacen wie DRM unter linux machst, spielt das keine
grosse rolle. Tatsächlich hängt es von der Grafigkarte ab, das memory
management ist bei jeder stark unterschiedlich. Intels in die CPU
integrierte Grafikkarten nutzen einfach den RAM. Bei richtigen
grafigkarten gibt es meistenns Videoram auf der Karte. Jenachdem kann
über DMA (im kernel/treiber) direckt auf Videospeicher zugegriffen
werden, teils können Grafigkarten per DMA sogar untereinander speicher
sharen, etc.
Danke schonmal, teilweise hatte es sich bei Dingen die ich gelesen habe
so angehört als ob es sich doch sehr zur normalen Programmierung
unterscheidet, dass zB auch Variablen anders sind, andere genauigkeiten
haben etc. Wäre es denn überhaupt möglich alle Datenstrukturen aus der
c++ STL zu nutzen?
Ich werde mich an OpenCL halten und mal versuchen ein paar tutorials
nachzuschreiben um reinzukommen mal sehen wie weit ich komme
Ich hatte mich fuer CUDA entschieden, und kann sagen: CUDA ist
saueinfach. (Natuerlich kann es auch beliebig kompliziert werden). Wenn
der Algorithmus schon parallelisierbar implementiert war hat man ihn
typischerweise in 2 Tagen auf der GPU (wie immer YMMV)
Mit OpenCl habe ich keine Erfahrung, wenn ich mir jedoch Beispiele
ansehe, dann ist entweder die Doku schlechter, oder es ist eine Stufe
komplizierter. Ich wuerde erstmal mit CUDA anfangen und erst wenn Dir
das zu einfach wird auf OpenCl umsteigen.
Dumdi D. schrieb:> Ich hatte mich fuer CUDA entschieden, und kann sagen: CUDA ist> saueinfach.
Das mag ja sein, aber: CUDA funktioniert nicht auf AMD und Intel GPUs,
es kann ausschlieslich auf NVIDIA GPUs verwendet werden. Tatsächlich
dürfen AMD und Intel CUDA garnicht implementieren. OpenCL hingegen läuft
auf allen modernen GPUs. Im gegensatz zu AMD ist es bei NVIDIA üblich
anderen Herstellern technologien vorzuenthalten und alles so closed
source wie möglich zu halten. Bei AMD ist das genaue gegenteil der fall.
Wenn dir Plattformunabhängigkeit egal ist und du mit den
Geschäftspraktiken von NVIDIA einverstanden bist, dann verwende eben
CUDA. Etwas zu verwenden, kaufen, etc. ist immer auch eine Politische
entscheidung. Ich jedenfalls verwende keine NVIDIA technologien, die
sind bei mir auf der Blacklist der Firmen mit Vendorlockingefahr und
unfairen Geschäftspraktiken.
Daniel A. schrieb:> Das mag ja sein, aber: CUDA funktioniert nicht auf AMD und Intel GPUs,> es kann ausschlieslich auf NVIDIA GPUs verwendet werden
Ich denk halt: lieber ersteinmal ein Programm das auf einer Plattform
läuft, als kein Programm das auf allen laufen würde.
Hast Du Erfahrungen mit OpenCl gemacht? Wie waren die?
Dumdi D. schrieb:> Hast Du Erfahrungen mit OpenCl gemacht? Wie waren die?
Vor einigen jahren hab ich es mal für ein paar tage ausprobiert. Damals
wollte ich es nur nutzen, um mit OpenCL statt mit OpenGL Bilder in
echtzeit zu rendern, um eine art rasterizer erstellen zu können, welcher
nicht auf Dreiecke beschränkt ist. Damals bin ich dann auf ein Problem
gestossen, das ich nicht selbst lösen konnte:
Beitrag "OpenGL/OpenCL kernel wird nicht ausgefürt" Im OpenCL Forum
https://forums.khronos.org wurde mir dann geholfen, es stellte sich
heraus, dass ich write_imagef statt write_imageui hätte verwenden
müssen. Danach hatte ich so viel anderes zutun, dass ich das Projekt
irgendwie vergessen habe. Man muss sich also schon sehr genau mit der
Materie beschäftigen, und man muss höllisch aufpassen alles immer
richtig zu initialisieren, aber ich finde es lohnt sich. Die Lernkurve
ist sehr Steil und sobald man alles verstanden hat ist es doch
eigentlich wieder recht einfach.
Dumdi D. schrieb:> lieber ersteinmal ein Programm das auf einer Plattform> läuft, als kein Programm das auf allen laufen würde.
Sehr geil ausgedrückt :) Das merk ich mir für diverse Meetings...
Dumdi D. schrieb:> Wenn> der Algorithmus schon parallelisierbar implementiert war hat man ihn> typischerweise in 2 Tagen auf der GPU (wie immer YMMV)
Naja das schließt dann wohl noch keine besonders aufwändigen
Optimierungen ein. Ich habe selbst für meine Bachelorarbeit Simulationen
auf Grafikkarten per CUDA gemacht und da sind mehrere Wochen für
Optimierung drauf gegangen. Mag sein das man als CUDA Anfänger in 2
Tagen eine erste lauffähige Version hinkriegt. Die läuft dann
Möglicherweise auch schon schneller als auf einer CPU, aber das absolute
Maximum hat man aus der Grafikkarte dann noch nicht rausgeholt. Das
erfordert auch einiges an speziellem Wissen über die Architektur der
benutzen Grafikkarte. Hängt aber auch vom speziellen Problem ab. Bei
aufwändigen Simulationen ist es halt doch wichtig ob die Simulation eine
oder zwei Wochen braucht.
Daniel A. schrieb:> A. Froh schrieb:>> # Und erstmal ganz naiv, kann man auf einer GPU grundsätzlich den>> gleichen Code ausführen wie auf einer CPU ? Wäre es möglich ein normales>> in C++ geschriebenes Programm auf einem "GPU Kern" auszuführen bzw kann>> man zB eine normale Funktion zu einer machen die auf der GPU laufen>> soll?>> Jein, grundsätzlich wären compiler backends für GPUs machbar, aber es> ist nicht wirklich sinvoll und jede Grafigkarte bräuchte ein neues> backend, und der code wäre darauf langsamer, etc. OpenCL ist aber sehr C> ähnlich und besser für GPUs und deren Paralellisierung geeignet.
In GCC gibt's eine HSA (Heterogeneous System Architecture), hier als
Präsentation von 2015:
https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=get&target=mjambor-hsa-slides.pdf
Inzwischen ist das im Hauptzweig von GCC gelandet.
Sebastian V. schrieb:> Naja das schließt dann wohl noch keine besonders aufwändigen> Optimierungen ein
Absolut richtig. Es hat sich dann noch ein Doktorand einer Arbeitsgruppe
mit GPU Erfahrung rangesetzt und nach 9 Monaten lief der Code dann
doppelt so schnell. Damit konnten wir dann die Anzahl der benoetigten
GPUs halbieren.
Was meine Aussage ist: mit CUDA bekommt man schnell brauchbare
Ergebnisse. Ob das mit OpenCl auch so ist: keine Ahnung, hab aber meine
Zweifel.