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 Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    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, muss 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 Codeberg-Repositories findet man hier.