Ich bin sehr neu in der GPGPU-Programmierung. Bitte verzeihen Sie mir, wenn die Frage nicht besonders geeignet ist. Soweit ich weiß, ist die GPU-Programmierung im Vergleich zur üblichen CPU-Programmierung eine sehr komplizierte technische Arbeit. Man muss sehr vorsichtig sein, wenn es um Divergenzprobleme, Kacheln, festgelegte Speicherzuweisung und Überlappung zwischen Kommunikation und Berechnung von Hostgeräten geht.
Nachdem ich ein wenig recherchiert hatte, fand ich die Schubbibliothek, die zu versuchen scheint, C ++ STL nachzuahmen. Das ist ganz nett. Aufgrund meiner sehr begrenzten Erfahrung und nachdem ich all das Mikromanagement gesehen habe, das für eine gute Leistung erforderlich ist, bin ich ein wenig skeptisch gegenüber der Leistung. Kann der Schub den komplizierten Programmierteil intern effizient handhaben? Einige sehr bekannte Bibliotheken wie PETSc scheinen dieses Paket zu verwenden, was mich glauben lässt, dass es irgendwie sollte.
Ich habe mich gefragt, ob Leute mit mehr Erfahrung in CUDA und Schub ein oder zwei Worte über die Leistung des Pakets im Vergleich zur CUDA-Programmierung auf niedriger Ebene sagen können. Wann kann ich Schub verwenden und wann sollte ich wieder zu CUDA wechseln?
quelle
Antworten:
Ich habe keine persönlichen Erfahrungen mit Schub, aber ich verwende ViennaCL, eine weitere GPU-Bibliothek auf hoher Ebene, die fast alle Details verbirgt. Aus meinem persönlichen Benchmarking kann ich eine Beschleunigung von 2x - 40x bei der tatsächlichen Berechnung erkennen, wenn Sie die Zeit ignorieren, die erforderlich ist, um sich im Speicher zu bewegen.
Wann Sie die CPU vs. Schub vs. CUDA verwenden sollten, hängt von dem Problem ab, das Sie lösen, Ihren Fähigkeiten und der verfügbaren Zeit. Ich würde empfehlen, zunächst einfache Probleme mit allen drei Methoden zu lösen, um deren relative Leistung zu ermitteln. Dann können Sie Ihre eigentliche Software schnell schreiben, sie vergleichen und die entsprechende GPU-Methode in den Bereichen anwenden, in denen eine Beschleunigung erforderlich ist, anstatt Ihre Zeit mit dem Schreiben von CUDA-Software zu verschwenden, die Ihnen nur ein paar Minuten Ausführungszeit einbringt .
quelle
Ich habe Thrust in meinem verknüpften Cluster-Erweiterungsprojekt verwendet. Abhängig von der Situation kann Thrust genauso gut oder besser als eine Implementierung auf niedriger Ebene sein, die Sie selbst rollen (insbesondere hat der
reduce
Kernel für mich recht gut funktioniert). Die generische Natur und Flexibilität von Thrust bedeutet jedoch, dass es manchmal viel zusätzliches Kopieren, Auffüllen von Arrays usw. erfordern muss, was es in einigen bösen Fällen erheblich verlangsamen kann. Das letzte Mal, als ich es benutztesort
, war es im Vergleich zu anderen Bibliotheken wie b40c oder mgpu ziemlich langsam. NVIDIA hat jedoch daran gearbeitet, die algorithmische Leistung von Thrust zu verbessern, sodass dies in Zukunft möglicherweise weniger problematisch ist.Sie sollten versuchen, Ihren Code sowohl mit Thrust als auch mit CUDA zu schreiben und dann mit dem Visual Profiler zu ermitteln, welcher für die jeweilige Aufgabe, an der Sie interessiert sind, besser geeignet ist. Wenn es wahrscheinlich ist, dass die Speicherübertragung die meiste Laufzeit Ihres Programms in Anspruch nimmt und Sie dies nicht tun Ich möchte mich nicht um die Optimierung Ihrer eigenen Kernel für Bankkonflikte, Befehlsanzahl usw. kümmern müssen, dann würde ich Thrust verwenden. Es hat auch den Nebeneffekt, dass Ihr Code für Personen, die mit der GPU-Programmierung nicht vertraut sind, weniger ausführlich und einfacher zu lesen ist.
quelle
Der Zweck von push (wie bei den meisten Vorlagenbibliotheken) besteht darin, eine Abstraktion auf hoher Ebene bereitzustellen und gleichzeitig eine gute oder sogar hervorragende Leistung zu erhalten.
Ich würde vorschlagen, sich nicht zu viele Sorgen um die Leistung zu machen, sondern sich zu fragen, ob
Ihre Anwendung kann anhand der im Schub implementierten Algorithmen beschrieben werden, und wenn
Sie mögen die Möglichkeit, "generischen" Parallelcode zu schreiben, ohne auf die wichtigsten Details eingehen zu müssen, um eine effiziente Zuordnung zu der angegebenen Hardware- / Softwarearchitektur zu finden.
Wenn Sie beide Fragen positiv beantworten, sollten Sie in der Lage sein, Ihr Programm mit weniger Aufwand in Bezug auf eine reine CUDA-Implementierung zu implementieren. Anschließend können Sie Ihre Anwendung profilieren und entscheiden, ob es sich lohnt, die Leistung zu verbessern.
Das heißt, ich muss gestehen, dass ich "generische" Programmierung nicht mag, weil ich bereit bin, etwas Neues zu lernen, wenn ich ein Programm schreibe. Ich würde einem anderen Weg folgen: Schreiben Sie eine Prototyp-Implementierung in Python + Numpy + Scipy und fügen Sie dann CUDA-Kernel für die 1% - 2% des Codes hinzu, die wirklich optimiert werden müssen und für die Ausführung auf einer GPU geeignet sind. Dazu benötigen Sie natürlich eine Art Vorwissenschaft, da eine falsche Entscheidung in der Prototyping-Phase (z. B. eine für CUDA-Kernel ungeeignete Datenstruktur) schreckliche Auswirkungen auf die Leistung haben kann. Normalerweise sind mehr Iterationen erforderlich, um einen guten Code zu erhalten, und es gibt keine Garantie dafür, dass es besser ist als Schub.
quelle