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

  • Fährnisse des Buildprozesses unter Windows

    17.07.2019

    Nachdem ich begonnen hatte, mich mit der Beschleunigung der Berechnung des Mandelbrot-Fraktals unter Zuhilfenahme der Shadereinheiten in Graphikkarten zu beschäftigen und erste Erfolge feiern konnte, wollte ich das mal auf einer richtigen Graphikkarte ausprobieren...

    Weiterlesen...

Neueste Artikel

  • Datenvalidierung UTF8 mit BiDi-Steuerzeichen (TrojanSource 2.0)

    Ich bin heute nochmal inspiriert worden, weiter über die Trojan Source Vulnerability nachzudenken. Meiner Meinung nach bestehen hier noch Probleme - speziell bei Nutzereingaben oder Daten, die über externe Schnittstellen ampfangen werden.

    Weiterlesen...
  • OpenStreetMap Navi als Docker-Container

    Ich habe die auf OpenStreetMap basierende OpenSource Navigationslösung Graphhopper in einen Docker-Container gepackt und als neuestes Mitglied in meinem Docker-Zoo willkommen geheißen.

    Weiterlesen...
  • SQL-Aggregatfunktionen in SQLite als BeanShell-Scripts

    Ich habe neulich über eine Möglichkeit berichtet, SQLite mittels der sQLshell und Beanshell-Skripten um SQL-Funktionen zu erweitern. In diesem Artikel versprach ich auch, über eine solche Möglichkeit für Aggregatfunktionen zu berichten.

    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.