OpenCL () ist eine Schnittstelle für uneinheitliche Parallelrechner, die z. B. mit Haupt-, Grafik- oder digitalen Signalprozessoren ausgestattet sind. Dazu gehört die Programmiersprache „OpenCL C“. OpenCL wurde ursprünglich von der Firma Apple entwickelt, um die Leistung der aktuellen Grafikprozessoren auch für nicht-grafische Anwendungen nutzbar zu machen.
Architektur
mini|Plattform-Modell
Ein OpenCL-System besteht aus einem Host und einem oder mehreren OpenCL-Geräten. Ein Gerät besteht aus einer oder mehreren unabhängigen Recheneinheiten (englisch „compute unit“, kurz „CU“). Dies sind bei einem Mehrkernprozessor die verfügbaren Kerne, die zusammengefasst die Central Processing Unit ergeben, und für die Grafikkarte die Shader. Die Compute Unit ist in ein oder mehrere ausführende Elemente (englisch „“, kurz „PE“) unterteilt. Der Host verteilt dabei die Kernel (Programme, dt. Kerne) zur Laufzeit auf die verfügbaren Geräte.
Es gibt zwei Arten von Kernel: OpenCL-Kernel Diese sind in der Programmiersprache OpenCL C geschrieben. OpenCL C basiert auf ISO C99 und wurde um Funktionen und Datentypen zur parallelen Verarbeitung erweitert. Native Kernel Diese Kernel sind optional und implementierungsspezifisch.
Die OpenCL-Kernel werden zur Laufzeit vom OpenCL-Compiler übersetzt und danach von einem OpenCL-Gerät ausgeführt. Hierdurch braucht zur Entwicklungszeit nicht bekannt zu sein, auf welcher Hardware das Programm später ausgeführt wird.
Die Berechnungen werden zur Laufzeit von den sogenannten Work-Items durchgeführt. Diese Work-Items werden zu einem ein-, zwei- oder dreidimensionalen Gitter angeordnet, über das die Work-Items adressiert werden können. Work-Items werden zu Work-Groups gruppiert, in denen eine Synchronisation möglich ist und die auf einen gemeinsamen Speicher zugreifen können. Ein einzelnes Work-Item kann also absolut, durch seine Koordinate und relativ, durch die Koordinate der es enthaltenden Work-Group und die Koordinate innerhalb der Work-Group angesprochen werden.
Speichermodell
mini|Speichermodell
In OpenCL werden fünf Arten von Speicher unterschieden: Hostspeicher (): Beim Hostspeicher handelt es sich um den regulären Arbeitsspeicher des Leitprogramms. Ein OpenCL-Kernel kann darauf nicht direkt zugreifen. globaler Speicher (): Hierbei handelt es sich um den Arbeitsspeicher der OpenCL-Kernel. Jede Instanz eines Kernels hat auf den gesamten Bereich wahlfreien Zugriff. konstanter Speicher (): Der konstante Speicher unterscheidet sich vom globalen Speicher darin, dass die Kernelinstanzen diesen Speicher ausschließlich lesen, aber nicht verändern können. lokaler Speicher (): Eine Gruppe von Kernelinstanzen hat wahlfreien Zugriff auf einen kleinen Bereich von typischerweise 16 kiB lokalen Speicher. Jede Gruppe hat ihren eigenen Bereich, auf den jeweils nur die Mitglieder zugreifen können. privater Speicher (): Dieser Speicher ist einer Kernelinstanz vorbehalten. Andere Kernelinstanzen und das Leitprogramm können nicht auf den Inhalt dieses Speichers zugreifen.
OpenCL C
Die Sprache OpenCL C basiert auf der Syntax von ISO C99, erweitert um zusätzliche Datentypen und Funktionen zur parallelen Verarbeitung, wurde an anderer Stelle aber auch eingeschränkt (siehe unten). Es handelt sich somit nicht um eine Obermenge von C, dennoch haben beide Sprachen viele Gemeinsamkeiten.
Ergänzend zu den C99-Datentypen unterstützt OpenCL C folgende Datentypen: half: 16 Bit Gleitkommazahlen nach IEEE 754r. Vektordatentypen: Die Datentypen char, uchar, short, ushort, int, uint, long, ulong und float gibt es als Vektoren mit 2, 4, 8 und 16 Elementen. Die Elementanzahl wird hierbei an den Namen der Datentypen angehängt, also z. B.: uchar4, float8 oder int16. Mit OpenCL 1.1 wurden zusätzlich drei-elementige Vektoren eingeführt. image2d_t: Ein zweidimensionales Bild. image3d_t: Ein dreidimensionales Bild. sampler_t: Ein sampler, der definiert, wie ein Bild abgetastet wird. event_t: Ein Ereignisbehandler.
Folgende Datentypen wurden zudem für spätere Versionen von OpenCL reserviert: booln: Ein Vektor mit Wahrheitswerten. double, doublen: 64-Bit-Gleitkommazahlen und -vektoren. Eine Erweiterung für double existiert bereits, deren Unterstützung ist aber bei OpenCL 1.0 nicht erforderlich. halfn: Ein Vektor mit 16-Bit-Gleitkommazahlen. quad, quadn: 128-Bit-Gleitkommazahlen. complex {half | float | double | quad}: Komplexe Zahlen mit unterschiedlicher Genauigkeit. complex {half | float | double | quad}n: Vektoren komplexer Zahlen mit unterschiedlicher Genauigkeit. imaginary {half | float | double | quad}: Imaginäre Zahlen mit unterschiedlicher Genauigkeit. imaginary {half | float | double | quad}n: Vektoren imaginärer Zahlen mit unterschiedlicher Genauigkeit. {float | double}nxm: nxm Matrizen mit 32 oder 64 Bit Genauigkeit. long double, long doublen: Gleitkommazahlen und -vektoren mit mindestens der Genauigkeit von double und maximal der Genauigkeit von quad. long long, long longn: Vorzeichenbehaftete 128-Bit-Ganzzahlen und -vektoren. unsigned long long, unsigned long longn: Vorzeichenlose 128-Bit-Ganzzahlen und -vektoren.
Arithmetische Operationen (+, -, *, /, %, ++, --), Vergleichsoperationen (>, >=, ==, !=, <= <), Bitoperatoren (&, |, ^, ~) sowie logische Operatoren (&&, ||) sind sowohl für skalare Datentypen definiert als auch für Vektoren. Werden sie auf Vektoren angewendet, so wird die Operation komponentenweise durchgeführt. Hier verhält sich OpenCL analog zu bekannten Shadersprachen wie zum Beispiel GLSL.
Ebenfalls den Shader-Sprachen entlehnt sind eine Reihe mathematischer Funktionen, die ebenfalls komponentenweise durchgeführt werden, beispielsweise Sinus, Cosinus, Wurzel, Minimum, Maximum etc.
Gegenüber C ist OpenCL C unter anderem in folgenden Punkten eingeschränkt: Es gibt keine Funktionszeiger Rekursion ist nicht möglich. Felder („arrays“) dürfen keine variable Länge haben.
Nutzung von OpenGL- und DirectX-Objekten
OpenCL kann direkt auf Objekte von OpenGL oder DirectX (nur unter Windows) zugreifen, etwa auf Texturen. Somit kann OpenCL genutzt werden, um beispielsweise Texturen zu ändern, ohne die Daten umkopieren zu müssen.
Erweiterungen
Wie OpenGL kann auch OpenCL durch herstellerspezifische Erweiterungen um zusätzliche Funktionen ergänzt werden. Beispiele für bereits definierte Erweiterungen sind: Gleitkommazahlen mit doppelter Genauigkeit (64-Bit-Gleitkommazahlen, cl_khr_fp64). Vektoren von Gleitkommazahlen mit halber Genauigkeit (16-Bit-Gleitkommazahlen, cl_khr_fp16). Die Art des Rundens bei Gleitkommaoperationen zu definieren (cl_khr_select_fprounding_mode). Schreiben in 3D-Bilder (cl_khr_3d_image_writes).
Versionsgeschichte
OpenCL wurde ursprünglich von der Firma Apple entwickelt.
In Zusammenarbeit mit den Firmen AMD, IBM, Intel und Nvidia wurde der erste Entwurf ausgearbeitet und schließlich von Apple bei der Khronos Group zur Standardisierung eingereicht.Khronos OpenCL API Registry Spezifikation und Headerdateien (englisch) Die Spezifikation für OpenCL 1.0 wurde am 8. Dezember 2008 veröffentlicht.developer.amd.com (PDF)khronos.org (PDF; 1,1 MB) Es folgte 1.1 im Juni 2010.khronos.org (PDF; 2,8 MB)khronos.org (PDF; 0,8 MB) Am 16. November 2011 folgte die Spezifikation 1.2 mit Verbesserungen, die zu 1.0 abwärtskompatibel bleibt.khronos.org (PDF; 2,8 MB)khronos.org (PDF; 1 MB) Zwei Jahre später, am 18. November 2013, wurde dann die OpenCL-2.0-Spezifikation eingeführt.khronos.org (PDF; 2,5 MB)khronos.org (PDF; 1 MB)
OpenCL 1.0 wurde erstmals am 28. August 2009 von Apple mit dem Betriebssystem Mac OS X Snow Leopard 10.6 auf den Markt gebracht, die dazugehörigen Programme („Kernel“) können zur Laufzeit auf verschiedene vorhandene OpenCL-fähige Geräte verteilt werden. Derzeit wird abhängig von der Hardware nur OpenCL 1.0 bis 1.2 von Apple unterstützt.OpenCL im Mac. Heise, 2014.OpenCL auf dem Mac-Rechnern. Apple-Support; nur OpenCL 1.0 bis 1.2 auf den macOS-Rechnern, kein OpenCL 2.x (Stand April 2016) Weiterer Hauptunterstützer ist AMD mit vorherigem AtiStream in Konkurrenz zu Nvidia mit CUDA.developer.amd.com (PDF) Trotz seiner primären Unterstützung von CUDA unterstützt Nvidia wegen der Nachfrage der Nutzer auch OpenCL 1.2, später mit einigen Elementen aus 2.0 und nun 2021 auch 3.0.developer.download.nvidia.com (PDF; 1,5 MB)
Mit OpenCL 2.0 kompatible Hardware unterstützt mit aktualisierten Treibern auch die höheren Versionen 2.1 und 2.2 laut Khronos-Group.Khronos OpenCL Overview 2.1. (PDF; 0,7 MB) Überblick von OpenCL 2.1 (englisch).
OpenCL 2.1 wurde im November 2015 offiziell freigegeben. Eine entscheidende Neuerung in OpenCL 2.1 ist die Integration von SPIR-V, dem SPIR-Nachfolger (Standard Portable Intermediate Representation). SPIR-V ist eine Zwischensprache mit nativer Unterstützung für Grafik-Shader und Prozessor-Kernels. Sie ermöglicht die Aufteilung der Compiler-Kette auf die unterschiedlichen Recheneinheiten. Somit können High-Level-Sprachen über SPIR-V die heterogene Architektur ansprechen, ohne sich selbst um die Übersetzung auf die unterschiedlichen Hardware-Komponenten zu kümmern. SPIR-V wird außer in OpenCL auch in der Vulkan-Grafik-API genutzt.khronos.org (PDF; 2,7 MB)khronos.org (PDF; 1,1 MB)
OpenCL 2.2 wurde offiziell freigegeben im Mai 2017.khronos.org Als wichtigste Änderung nennt die Bekanntmachung die Integration der OpenCL C++ Kernel Language in OpenCL, was unter anderem beim Schreiben parallel arbeitender Programme helfen soll. Die im Rahmen der Open Computing Language als statische Untermenge des C++14-Standards definierte Kernel-Sprache enthält Klassen, Templates, Lambda-Ausdrücke und andere Konstrukte. Im Mai 2018 erschien ein „maintenance update“ mit Fehlerkorrekturen und Aktualisierungen in den Headern von Spir-V.khronos.orgkhronos.org (PDF; 3,5 MB)khronos.org (PDF; 1,4 MB)
In Zukunft soll OpenCL mit Vulkan so weit wie möglich verschmelzen und so noch breitere Unterstützung gewinnen.pcper.comphoronix.com Dies wurde mit dem Premiere Rush von Apple gezeigt, der den Open Source Compiler clspvgithub.com benutzt, um einen großen Teil des OpenCL C Kernel Codes für eine Vulkan-Umgebung auf Android-Geräten zu kompilieren. Zuletzt wurde nun OpenCL Next für 2019 angekündigt mit neuen Informationen und dabei auch betont, dass die „roadmap“ von OpenCL von der von Vulkan unabhängig ist, also beide Projekte nicht völlig fusionieren werden.phoronix.com
Am 27. April 2020 wurde OpenCL 3.0 (provisional) veröffentlicht.phoronix.com Der Status Final wurde am 30. September 2020 erreicht.khronos.org (PDF; 2 MB)khronos.org (PDF; 1,1 MB)
Auf der IWOCL 2021 wurde Version 3.0.7 mit einigen optionalen Erweiterungen angekündigt.iwocl.org (PDF)
Implementierungen OpenCL kann für beliebige Betriebssysteme und Hardwareplattformen – genau wie OpenGL und OpenAL – implementiert werden. So ist in der Spezifikation von CPUs, GPUs, DSPs und dem Cell-Prozessor die Rede. Es existiert zudem eine Spezifikation für eingebettete Systeme mit reduzierten Anforderungen.
Aktuelle Implementierungen, in der Regel Open Source (mit Ausnahme von Nvidia):