GPU-Programmierung in Java revisited

vorhergehende Artikel in: Java Revisited Komponenten
29.07.2020

Ich habe vor einiger Zeit darüber berichtet, wie man die GPU einer Graphikkarte auch zur Unterstützung und sogar Beschleunigung komplexer Berechnungen aus Java-Anwendungen heraus benutzen kann. Es ist sogar möglich, für einfache Berechnungen Graphikkarten, die das von Haus aus nicht beherrschen, dazu zu bringen, mit doppelter Genauigkeit zu rechnen.

Diese ersten Erfolge haben mich ermutigt, nun auch zu versuchen, diese Berechnungen "ordentlich" durchzuführen. Die ersten Schritte auf meinem Weg waren ja eher krude: Ich berechnete ein Mandelbrotfraktal und stellte es mit einem Shader sofort dar - ich konnte aber auf die (numerischen) Ergebnisse der Berechnungen in der Java-Anwendung nicht zurückgreifen. Es war also klar, dass weitere Experimente folgen mussten.

Nachdem in der letzten Woche einige Tage Regenwetter zu verzeichnen waren, habe ich das Projekt noch einmal hervorgeholt. Da ich natürlicherweise faul bin überlegte ich zunächt, ob es nicht möglich wäre, alles etwas einfacher zu gestalten. Ich habe mich von vornherein auf OpenCL festgelegt und gegen CUDA entschieden. Trotz allem wollte ich eine einfache Möglichkeit haben, aus Java heraus die entsprechenden Programme auf die GPU zu laden und auszuführen, sowie den Transfer von Daten zwischen dem Arbeitsspeicher der CPU und der GPU so schmerzfrei wie möglich zu gestalten.

Daher war zunächst erst einmal eine Internet-Recherche anberaumt. Und siehe da: Ich wurde fündig. Eine Bibliothek, die meine kühnsten Erwartungen übertraf trat in Gestalt von A Parallel API (aparapi) in mein Leben. Dank einiger Beispiele feierte ich beinahe sofort erste Erfolge.

Das Beste daran: man schreibt puren Java-Code, der durch die Bibliothek selber zur Laufzeit in kompilierten OpenCL-Code verwandelt wird, der anschließend auf der Graphikkarte ausgeführt wird. Auch wenn man die Bibliothek benutzt bleibt die Anwendung portabel - Auf Systemen ohne Beschleuniger-Karte wird der Code einfach mit mehreren Threads parallel auf der CPU ausgeführt - ein Verhalten, das man allerdings abschalten kann...

Ich habe damit erfolgreich erste Experimente mit (womit auch sonst?) dem Mandelbrot-Fraktal ausgeführt.

Ich habe im Zuge dessen auch an meiner alten Bildverarbeitungsbibliothek weitergearbeitet und jede Menge Bugs entfernt, neue Features (Diskrete Fourier-Transformation) hinzugefügt und wollte auf dieser Basis mit der GPU verschiedene Funktionen beschleunigen. Die Bugfixes und die neuen Features sind noch nicht in das entsprechende Repository eingeflossen.

Es stellte sich heraus, dass meine Anstrengungen für die Optimierung der Bildverarbeitungsalgorithmen Früchte getragen hatte: Die Variante mit Graphikkartennutzung war langsamer als die Abarbeitung auf der CPU - selbst bei Benutzung nur eines Threads. Es ist angedacht, zu einem späteren Zeitpunkt exemplarisch zu Testzwecken einige Algorithmen auf Multithreading umzustellen.

Die Tatsache, dass die GPU langsamer war als die CPU schreibe ich dem Fakt zu, dass die für die eigentliche Berechnung zur Rotation eines Bildes mit bilinearer Filterung der Auflösung 800x600 Pixel benötigte Zeit neben der zum Kopieren der Bilddaten in den Speicher der GPU und dem Kopieren des Resultats zurück in den der CPU zu vernachlässigen ist.

Zum Abschluss daher hier nochmal meine Messergebnisse (die erste Zahl weicht jeweils deutlich ab, weil hier der Jit noch nicht zum Zuge kam, bzw. der OpenCL-Code erst noch kompiliert werden musste...

Ohne Graphikkarte auf Core-i 550:
00:00:00.142466
00:00:00.029809
00:00:00.031769
00:00:00.037841
00:00:00.035090
Mit Graphikkarte auf Core-i 550:
00:00:01.804669
00:00:00.159230
00:00:00.150285
00:00:00.166760
00:00:00.171283
Ohne Grafikkarte auf Core-i 2100
00:00:00.065103
00:00:00.028241
00:00:00.034993
00:00:00.020167
00:00:00.019394

Artikel, die hierher verlinken

Bildverarbeitung in Java multi-threaded

13.08.2020

Ich habe vor einiger Zeit darüber berichtet, dass ich eine alte Bibliothek zur Bildverarbeitung von C++ nach Java portiert habe. Ich habe sie inzwischen poliert und um neue Features ergänzt...

Alle Artikel rss Wochenübersicht Monatsübersicht Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Certstream, InfluxDB, Grafana und Netflix

    16.04.2019

    Nachdem ich vor kurzem über mein erstes Spielen mit dem certstream berichtete, habe ich weitere Experimente gemacht und die Daten zur besseren Auswertung in eine InfluxDB gepackt, um sie mit Grafana untersuchen zu können.

    Weiterlesen...

Neueste Artikel

  • Die sQLshell ist nun cloudnative!

    Die sQLshell hat eine weitere Integration erfahren - obwohl ich eigentlich selber nicht viel dazu tun musste: Es existiert ein Projekt/Produkt namens steampipe, dessen Slogan ist select * from cloud; - Im Prinzip eine Wrapperschicht um diverse (laut Eigenwerbung mehr als 140) (cloud) data sources.

    Weiterlesen...
  • LinkCollections 2024 III

    Nach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2024 folgt hier gleich die nächste:

    Weiterlesen...
  • Funktionen mit mehreren Rückgabewerten in Java

    Da ich seit nunmehr einem Jahr bei meinem neeun Arbeitgeber beschäftigt und damit seit ungefähr derselben Zeit für Geld mit Python arbeite, haben sich gewisse Antipathien gegenüber Python vertieft (ich kann mit typlosen Sprachen einfach nicht umgehen) - aber auch einige meiner Gründe, Python zu lieben sind ebenso stärker geworden. Einer davon ist der Fakt, dass eine Methode in Python mehr als einen Wert zurückgeben kann.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muß damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.