Java OpenCL für Java

Krik

Fleet Admiral Pro
Registriert
Juni 2005
Beiträge
17.978
Moin zusammen,


hat jemand von euch sich schon mal mit OpenCL unter Java beschäftigt? So, wie ich es gefunden habe, gibt es drei nennenswerte Bindings: JOCL, JOGAMP und JavaCL.

In diesem Paper werden sie miteinander verglichen: http://e-archivo.uc3m.es/bitstream/10016/17183/5/finalversionPFC_Raquel_Medina.pdf
Wenn man danach geht, ist JOGAMP die schnellste, JOCL die speicherschonenste und JavaCL die Programmierer-freundlichste Option.

Hat jemand schon mit einem davon gearbeitet oder kann ein paar Eindrücke schreiben? Also auf was man achten sollte, wie einfach sich die Programmierung gestaltet usw. Alltagserfahrungen eben.


Gruß
Laurin
 
Tut mir leid, ich könnte dir höchstens mit normalen OpenCL weiterhelfen; da würde ich dir ersteinmal raten, sofern es um GPGPU geht und dein Avatar nicht eine Präferenz für sekundäre weibliche Geschlechtsmerkmale sondern für einen Hardware-Hersteller symbolisiert unbedingt die entsprechenden Hardwaredokumentationen von AMD durchzulesen:
http://developer.amd.com/download/AMD_Accelerated_Parallel_Processing_OpenCL_Programming_Guide.pdf

Denn meine Erfahrungen selbst mit Java OpenCL und OpenGL Wrappern sind mittlerweile 2 oder 3 Jahre alt. Damals waren diese ein echter Graus (sogar noch schlimmer als OpenCL an sich). So besaßen sie nicht dokumentierte Funktionsargumente, welche in den C-OpenGL/C-OpenGL Funktionen nicht vorhanden waren, hatten viele Bugs und crashten oft. Das Ganze war eher so eine einmal und nie wieder Erfahrung. Allerdings scheinen zumindest die nicht dokumentierten Funktionsargumente nicht mehr vorhanden zu sein. Deshalb äußere bitte unbedingt deine Erfahrungen sobald du dich eingearbeitet hast.

Außerdem wäre ich mit dem Paper etwas vorsichtig, da es gelinde gesagt relativ beschissen ist. So hat er sich als Benchmark die Vektormultiplikation gewählt bei welchem er den Speichertransfer zur GPU mit benchmarkt. Dadurch ist das Benchmark sehr stark PCI-E-Bandbreiten limitiert, wodurch eine CPU-Implementierung schneller wäre. Da er jedoch bei der CPU -Implementierung noch zusätzlich das Array-Allozieren und durch Zufallszahlen befüllen benchmarkt, erreicht er, dass die GPU-Implementierung dennoch schneller ist. Bei der JOCL-Implementierung benchmarkt er nur die Kernelausführung und das Zurückkopieren allerdings ohne DMA, wodurch es am wenigsten Speicherplatz benötigt und am langsamsten ist. Bei JOGAMP benchmarkt er die Kernelausführung, das Hin- und Zurückkoperien mit abstraker Wrapper-Funktionalität, welche vermutlich DMA ausnutzt, wodurch sie schneller ist. Bei Java-CL benchmarkt er zusätzlich den Create-Kernel-Aufruf (daher der größere Overhead dieser Messreihe?) und nur die Kernelausführung und das Zurückkoperien mit abstraker Wrapper Funktionalität. Dem Speicherplatzverbrauch und der Laufzeit nach zu urteilen, verwendet es ebenfalls DMA. Dadurch, dass er jedemal etwas unterschiedliches benchmarkt, ist der Vergleich der Wrapper sehr unaussagekräftig.
 
Zuletzt bearbeitet:
Ich finde das Paper auch nicht besonders, deswegen habe ich hier den Thread aufgemacht. ;)


Von OpenCL habe ich keine Ahnung. Auf den ersten Blick schaut es wie C aus (kein Wunder, da es sich an die C99-Spezifikation hält). Ich denke, wenn man sich an ein paar Grundregeln hält (Erfahrungen, die auf CPUs zutreffen, müssen nicht auch auf GPUs zutreffen), sollte das keine größeren Probleme bereiten. Einarbeiten muss ich mich aber noch.

Crashs habe ich bei den ersten Versuchen mit JavaCL noch keine gehabt. Allerdings sind die Tutorials auf deren Seite veraltet. Da guckt man erst mal blöde, weil ein paar Methodensignaturen sich mit der Zeit geändert haben.

Ich bin mir noch nicht ganz sicher, ob ich letztendlich auf Java setzen werde. C#/.Net wäre noch eine Alternative. Dazu habe ich diese Seite mit vielen Tutorials gefunden. Mir gefällt, dass dort auch auf OpenCL und dessen Besonderheiten eingegangen wird.


Vielen Dank für deine Antwort! :)
 
Von OpenCL habe ich keine Ahnung. Auf den ersten Blick schaut es wie C aus (kein Wunder, da es sich an die C99-Spezifikation hält). Ich denke, wenn man sich an ein paar Grundregeln hält (Erfahrungen, die auf CPUs zutreffen, müssen nicht auch auf GPUs zutreffen), sollte das keine größeren Probleme bereiten. Einarbeiten muss ich mich aber noch.

Das ist auch generell neben vielen Kleinigkeiten so das Hauptproblem, was ich an OpenCL gegenüber CUDA nicht mag. Statt sich auf einen Device-Typ wie GPUs zu spezialisieren und obwohl es de facto fast nur für GPGPU verwendet wird, versucht krampfhaft eine Device-unabhängige eierlegende Woll-Milch-Sau zu sein. Die angezielten Devices (Cell, CPU, GPU, FPGA) sind jedoch von Grund auf verschieden. Aus diesem Grund kennt es wesentliche GPGPU-Konzepte nicht (Coalescing, Shared/Local-Memory-Bank-Conflicts, Warps/Wavefronts, Occupancy, DMA, die Limitierungen des Konstantenspeichers). Wegen den großen Unterschieden zwischen den Devices kann man auch nicht allgemein optimieren, sondern muss sich irgendeinen Device-Typ herauspicken. OpenCL spezifiziert von keinem Device-Typ jedoch genauere Eigenschaften. Das heißt beim Optimieren muss man dann erst einmal die jeweiligen Hardware-Dokumentationen studieren und Gemeinsamkeiten heraussuchen, denn zumindest zwischen aktuellen AMD und NVIDIA GPUs gibt es recht viele. Optimieren ist jedoch bei GPGPU meist unerlässlich da GPUs einfache Rechner sind, welche einem nicht so wie CPUs kleinere Optimierungs-Fehler vergeben. Letztendlich kommt dann etwas raus, was dann vermutlich auf aktuellen AMD und NVIDIA-GPUs performant funktioniert, allerdings auf anderen Devices (und eventuell sogar auf anderen GPUs) langsam läuft oder gar nicht mehr funktioniert. Im Gegensatz zu OpenCL löst CUDA das Problem elegant dadurch, dass diverse grundlegende GPU-spezifische Eigenschaften garantiert werden und abfragbar sind.

Zudem besitzt es die harten Limitierungen von allen unterstützten Devices (keine Rekursion, keine Read/Write Operation auf Bildern, kein Malloc/New), selbst obwohl sie auf einigen unterstützten Devices zum Teil auch auf einigen GPUs problemlos möglich wären. Viele Device-Spezifische Hardware-Features fehlen auch in OpenCL (zB. aus CUDA: Warp-Shuffle-Functions, L1-Cache-Konfiguration, uvm).

So ist OpenCL sicherlich ganz gut, wenn man einfach nur parallelen Device-unabhängigen Code schreiben will, aber sobald man Interesse an einer Optimierung hat, so stößt man mit OpenCL sehr schnell an dessen Grenzen.
 
Zuletzt bearbeitet:
Nai schrieb:
So ist OpenCL sicherlich ganz gut, wenn man einfach nur parallelen Device-unabhängigen Code schreiben will, aber sobald man Interesse an einer Optimierung hat, so stößt man mit OpenCL sehr schnell an dessen Grenzen.
Paralleler geräteunabhängiger Code reicht mir für den Anfang. Soweit ich es jetzt überblicken kann, muss der Code am Ende auf allem laufen, angefangen bei AMD und Intel CPUs bis hin zu AMD, Nvidia und Intel GPUs. Für jedes Geräte spezifischen Code zu schreiben, wäre mir jetzt zu viel und ist auch nicht gefordert.
Im Prinzip reicht es, wenn es auf jeder beliebigen CPU läuft. GPUs sind nur die goldenen Wasserhähne, die ich aber gerne mit dabei hätte.


Zur Anwendung:
Das Programm soll mehrere Fotos mit diversen Filtern verarbeiten und aus den Ergebnissen ein neues Bild generieren. Da es sich hier um semiprofessionelle Fotografie handelt und die Bilder und deren Anzahl deswegen recht groß sind, halte ich es für besser, mir Optionen wie OpenCL offen zu halten. Die Datenmengen können hier locker in den Bereich 10-20 Bilder a 12 MPixel gehen (= mehrere hundert MBytes), da brauche ich einfach massiv Rechenpower oder alternativ genügend Geduld.

Bildverarbeitung (bzw. Vektorrechnung) ist ja das Gebiet, auf das GPUs spezialisiert sind und OpenCL bietet mir einen Weg, sie optional zu nutzen. Wenn die Verarbeitung dann nur noch eine Minute statt einer Viertelstunde dauert, ist das für mich ausreichend. Um die letzten Prozente Leistung herauszukitzeln (sodass es nur noch Sekunden dauert), habe ich leider keine Zeit. Ich muss Kompromisse machen.
 
Handelt es sich bei den Filtern um einfache (Faltungs)-Filter ? Wenn ja kann man in diesem Speziellen Fall eh keine großen Optimierungen sondern nur relativ viel Fine-Tuning machen.
 
Zuletzt bearbeitet:
Nein. Die Bilder sollen gegebenenfalls transformiert und hinterher eine Kantenerkennung drübergejagt werden, um bestimmte Bereiche erkennen zu können. Wobei noch nicht ganz klar ist, ob wirklich eine Kantenerkennung verwendet werden soll. Es gibt für den angestrebten Anwendungsfall auch ein paar andere Algorithmen, die nützlich erscheinen.

Mal abwarten. Erst mal muss ich mir die Ausgangsvoraussetzungen und das Zielergebnis genau anschauen. Dann suche ich mir passende Algorithmen und wähle davon vielleicht die besten zwei oder drei aus (oder nur einen, je nachdem) und erst dann werde ich mit der Programmierung anfangen.
 
Zurück
Oben