OpenCL - OpenCL

OpenCL-API
OpenCL-Logo
Originalautor(en) Apple Inc.
Entwickler Chronos-Gruppe
Erstveröffentlichung 28. August 2009 ; vor 12 Jahren ( 2009-08-28 )
Stabile Version
3.0 / 30.09.2020 ; vor 12 Monaten ( 2020-09-30 )
Geschrieben in C mit C++- Bindungen
Betriebssystem Android (herstellerabhängig), FreeBSD , Linux , macOS (über Pocl), Windows
Plattform ARMv7 , ARMv8 , Zelle , IA-32 , POWER , x86-64
Typ Heterogene Computing- API
Lizenz OpenCL-Spezifikationslizenz
Webseite www .khronos .org / OpenCL /
OpenCL C/C++ und C++ für OpenCL
Paradigma Imperativ ( prozedural ), strukturiert , (nur C++) objektorientiert , generische Programmierung
Familie C
Stabile Version
OpenCL C++ 1.0 Revision V2.2-11

OpenCL C 3.0-Revision V3.0.7

C++ für OpenCL 1.0 Revision 2

/ 31. März 2021 ; vor 6 Monaten ( 2021-03-31 )
Schreibdisziplin Statisch , schwach , manifest , nominell
Implementierungssprache Implementierungsspezifisch
Dateinamenerweiterungen .cl .clcpp
Webseite www .khronos .org / OpenCL
Wichtige Implementierungen
AMD, Apple, Freeocl, Gallium Compute, IBM, Intel Beignet, Intel SDK, Texas Instruments, Nvidia, POCL, Arm
Beeinflusst von
C99 , CUDA , C++14 , C++17

OpenCL ( Open Computing Language ) ist ein Framework zum Schreiben von Programmen, die auf heterogenen Plattformen ausgeführt werden, bestehend aus Zentralprozessoren (CPUs), Grafikprozessoren (GPUs), digitalen Signalprozessoren (DSPs), feldprogrammierbaren Gate-Arrays (FPGAs) und anderen Prozessoren oder Hardwarebeschleuniger . OpenCL spezifiziert Programmiersprachen (basierend auf C99 , C++14 und C++17 ) zum Programmieren dieser Geräte und Anwendungsprogrammierschnittstellen (APIs), um die Plattform zu steuern und Programme auf den Computergeräten auszuführen . OpenCL bietet eine Standardschnittstelle für paralleles Computing mit aufgaben- und datenbasierter Parallelität .

OpenCL ist ein offener Standard, der vom gemeinnützigen Technologiekonsortium Khronos Group verwaltet wird . Konforme Implementierungen sind von Altera , AMD , ARM , Creative , IBM , Imagination , Intel , Nvidia , Qualcomm , Samsung , Vivante , Xilinx und ZiiLABS erhältlich .

Überblick

OpenCL sieht ein Rechensystem , wie eine Anzahl von aus Rechenvorrichtungen , die möglicherweise zentrale Verarbeitungseinheiten (CPUs) oder „Beschleuniger“ , wie beispielsweise Grafikverarbeitungseinheiten (GPUs), die an einen Host - Prozessor (eine CPU). Es definiert eine C-ähnliche Sprache zum Schreiben von Programmen. Auf einem OpenCL-Gerät ausgeführte Funktionen werden als " Kernel " bezeichnet. Ein einzelnes Rechengerät besteht typischerweise aus mehreren Recheneinheiten , die wiederum mehrere Verarbeitungselemente (PEs) umfassen. Eine einzelne Kernel-Ausführung kann auf allen oder vielen PEs parallel ausgeführt werden. Wie ein Rechengerät in Recheneinheiten und PEs unterteilt wird, liegt beim Anbieter; eine Recheneinheit kann als „ Kern “ betrachtet werden, aber der Begriff des Kerns ist für alle von OpenCL unterstützten Gerätetypen (oder sogar innerhalb der Kategorie der „CPUs“) schwer zu definieren, und die Anzahl der Recheneinheiten kann entspricht nicht der Anzahl der Kerne, die in der Marketingliteratur der Anbieter angegeben sind (die möglicherweise SIMD-Lanes zählt ).

Zusätzlich zu seiner C-ähnlichen Programmiersprache definiert OpenCL eine Anwendungsprogrammierschnittstelle (API), die es auf dem Host laufenden Programmen ermöglicht, Kernel auf den Rechengeräten zu starten und den Gerätespeicher zu verwalten, der (zumindest konzeptionell) vom Hostspeicher getrennt ist. Programme in der OpenCL-Sprache sollen zur Laufzeit kompiliert werden , sodass OpenCL-verwendende Anwendungen zwischen Implementierungen für verschiedene Hostgeräte portierbar sind. Der OpenCL-Standard definiert Host-APIs für C und C++ ; APIs von Drittanbietern existieren für andere Programmiersprachen und Plattformen wie Python , Java , Perl , D und .NET . Eine Implementierung des OpenCL-Standards besteht aus einer Bibliothek , die die API für C und C++ implementiert, und einem OpenCL-C- Compiler für das/die anvisierte(n) Rechengerät(e).

Um das OpenCL-Programmiermodell für andere Sprachen zu öffnen oder die Kernel-Quelle vor Inspektionen zu schützen, kann die Standard Portable Intermediate Representation (SPIR) als zielunabhängige Möglichkeit verwendet werden, Kernel zwischen einem Front-End-Compiler und dem OpenCL-Back zu versenden -Ende.

Vor kurzem hat die Khronos Group SYCL , ein übergeordnetes Programmiermodell für OpenCL, als Single-Source- DSEL auf Basis von reinem C++17 ratifiziert , um die Programmierproduktivität zu verbessern . Darüber hinaus können C++-Funktionen auch verwendet werden, wenn Rechenkernelquellen in C++ für die OpenCL-Sprache implementiert werden.

Speicherhierarchie

OpenCL definiert eine vierstufige Speicherhierarchie für das Rechengerät:

  • globaler Speicher: wird von allen Verarbeitungselementen geteilt, hat aber eine hohe Zugriffslatenz ( __global );
  • Nur-Lese-Speicher: kleiner, geringe Latenz, beschreibbar von der Host-CPU, aber nicht von den Rechengeräten ( __constant );
  • lokaler Speicher: geteilt von einer Gruppe von Verarbeitungselementen ( __local );
  • pro Element privater Speicher ( registers ; __private ).

Nicht jedes Gerät muss jede Ebene dieser Hierarchie in Hardware implementieren. Die Konsistenz zwischen den verschiedenen Hierarchieebenen wird gelockert und nur durch explizite Synchronisationskonstrukte , insbesondere Barrieren , erzwungen .

Geräte können Speicher mit der Host-CPU teilen oder nicht. Die Host-API stellt Handles für Gerätespeicherpuffer und Funktionen bereit , um Daten zwischen Host und Geräten hin und her zu übertragen.

OpenCL-Kernelsprache

Die Programmiersprache, die zum Schreiben von Rechenkernen verwendet wird, wird als Kernelsprache bezeichnet. OpenCL verwendet C / C++- basierte Sprachen, um die auf dem Gerät durchgeführten Kernel-Berechnungen mit einigen Einschränkungen und Ergänzungen zu spezifizieren, um eine effiziente Zuordnung zu den heterogenen Hardware-Ressourcen von Beschleunigern zu ermöglichen. Traditionell wurde OpenCL C verwendet, um die Beschleuniger im OpenCL-Standard zu programmieren, später wurde C++ für die OpenCL-Kernelsprache entwickelt, die alle Funktionen von OpenCL C erbte, aber die Verwendung von C++-Funktionen in den Kernelquellen erlaubte.

OpenCL C-Sprache

OpenCL C ist ein C99- basierter Sprachdialekt, der an das Gerätemodell in OpenCL angepasst ist. Speicherpuffer befinden sich in bestimmten Ebenen der Speicherhierarchie und Zeiger werden mit den Regionsqualifizierern __global , __local , __constant und __private annotiert , was dies widerspiegelt. Anstelle einer Programmvorrichtung eine mit Haupt sind Funktion, OpenCL C Funktionen markiert __kernel zu signalisieren , dass sie Eingangspunkte in das Programm vom Host - Programm aufgerufen werden. Funktionszeiger , Bitfelder und Arrays variabler Länge werden weggelassen und Rekursion ist verboten. Die C-Standardbibliothek wird durch einen benutzerdefinierten Satz von Standardfunktionen ersetzt, die auf die mathematische Programmierung ausgerichtet sind.

OpenCL C wurde erweitert, um die Verwendung von Parallelität mit Vektortypen und -operationen, Synchronisation und Funktionen für die Arbeit mit Arbeitselementen und Arbeitsgruppen zu erleichtern . Neben skalaren Typen wie float und double , die sich ähnlich wie die entsprechenden Typen in C verhalten, bietet OpenCL insbesondere Vektortypen mit fester Länge wie float4 (4-Vektor von Floats mit einfacher Genauigkeit); solche Vektortypen sind in den Längen zwei, drei, vier, acht und sechzehn für verschiedene Basistypen erhältlich. Vektorisierte Operationen dieser Typen sollen auf SIMD- Befehlssätze abgebildet werden, zB SSE oder VMX , wenn OpenCL-Programme auf CPUs ausgeführt werden. Andere spezialisierte Typen umfassen 2-D- und 3-D-Bildtypen.

Beispiel: Matrix-Vektor-Multiplikation

Jeder Aufruf ( work-item ) des Kernels nimmt eine Zeile der grünen Matrix ( A im Code), multipliziert diese Zeile mit dem roten Vektor ( x ) und platziert das Ergebnis in einem Eintrag des blauen Vektors ( y ). Die Anzahl der Spalten n wird als ncols an den Kernel übergeben ; die Anzahl der Zeilen ist in der Anzahl der vom Hostprogramm erzeugten Arbeitselemente implizit enthalten.

Das Folgende ist ein Matrix-Vektor-Multiplikationsalgorithmus in OpenCL C.

// Multiplies A*x, leaving the result in y.
// A is a row-major matrix, meaning the (i,j) element is at A[i*ncols+j].
__kernel void matvec(__global const float *A, __global const float *x,
                     uint ncols, __global float *y)
{
    size_t i = get_global_id(0);              // Global id, used as the row index
    __global float const *a = &A[i*ncols];    // Pointer to the i'th row
    float sum = 0.f;                          // Accumulator for dot product
    for (size_t j = 0; j < ncols; j++) {
        sum += a[j] * x[j];
    }
    y[i] = sum;
}

Die Kernelfunktion matvec berechnet bei jedem Aufruf das Skalarprodukt einer einzelnen Zeile einer Matrix A und eines Vektors x :

.

So erweitern Sie diese in eine vollständige Matrix-Vektor - Multiplikation, die OpenCL - Laufzeit abbildet den Kernel über die Zeilen der Matrix. Auf der Hostseite erledigt dies die Funktion clEnqueueNDRangeKernel ; es nimmt als Argumente den auszuführenden Kernel, seine Argumente und eine Anzahl von Arbeitselementen, entsprechend der Anzahl der Zeilen in der Matrix A .

Beispiel: Berechnung der FFT

In diesem Beispiel wird eine Implementierung einer schnellen Fourier-Transformation (FFT) geladen und ausgeführt. Die Implementierung ist unten gezeigt. Der Code fragt die OpenCL-Bibliothek nach der ersten verfügbaren Grafikkarte, erstellt Speicherpuffer zum Lesen und Schreiben (aus Sicht der Grafikkarte), JIT-kompiliert den FFT-Kernel und führt schließlich den Kernel asynchron aus. Das Ergebnis der Transformation wird in diesem Beispiel nicht gelesen.

#include <stdio.h>
#include <time.h>
#include "CL/opencl.h"

#define NUM_ENTRIES 1024

int main() // (int argc, const char* argv[])
{
	// CONSTANTS
	// The source code of the kernel is represented as a string
	// located inside file: "fft1D_1024_kernel_src.cl". For the details see the next listing.
	const char *KernelSource =
		#include "fft1D_1024_kernel_src.cl"
			;

	// Looking up the available GPUs
	const cl_uint num = 1;
	clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 0, NULL, (cl_uint*)&num);

	cl_device_id devices[1];
	clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, num, devices, NULL);

	// create a compute context with GPU device
	cl_context context = clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU, NULL, NULL, NULL);

	// create a command queue
	clGetDeviceIDs(NULL, CL_DEVICE_TYPE_DEFAULT, 1, devices, NULL);
	cl_command_queue queue = clCreateCommandQueue(context, devices[0], 0, NULL);

	// allocate the buffer memory objects
	cl_mem memobjs[] = { clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * 2 * NUM_ENTRIES, NULL, NULL),
						 clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * 2 * NUM_ENTRIES, NULL, NULL) };
	// cl_mem memobjs[0] = // FIXED, SEE ABOVE
	// cl_mem memobjs[1] = // FIXED, SEE ABOVE

	// create the compute program
	// const char* fft1D_1024_kernel_src[1] = {  };
	cl_program program = clCreateProgramWithSource(context, 1, (const char **)& KernelSource, NULL, NULL);

	// build the compute program executable
	clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

	// create the compute kernel
	cl_kernel kernel = clCreateKernel(program, "fft1D_1024", NULL);

	// set the args values

	size_t local_work_size[1] = { 256 };

	clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobjs[0]);
	clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobjs[1]);
	clSetKernelArg(kernel, 2, sizeof(float)*(local_work_size[0] + 1) * 16, NULL);
	clSetKernelArg(kernel, 3, sizeof(float)*(local_work_size[0] + 1) * 16, NULL);

	// create N-D range object with work-item dimensions and execute kernel
	size_t global_work_size[1] = { 256 };
	
	global_work_size[0] = NUM_ENTRIES;
	local_work_size[0] = 64; //Nvidia: 192 or 256
	clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_work_size, local_work_size, 0, NULL, NULL);
}

Die eigentliche Berechnung in der Datei "fft1D_1024_kernel_src.cl" (basierend auf Fitting FFT on the G80 Architecture ):

R"(
  // This kernel computes FFT of length 1024. The 1024 length FFT is decomposed into
  // calls to a radix 16 function, another radix 16 function and then a radix 4 function

  __kernel void fft1D_1024 (__global float2 *in, __global float2 *out,
                          __local float *sMemx, __local float *sMemy) {
    int tid = get_local_id(0);
    int blockIdx = get_group_id(0) * 1024 + tid;
    float2 data[16];

    // starting index of data to/from global memory
    in = in + blockIdx;  out = out + blockIdx;

    globalLoads(data, in, 64); // coalesced global reads
    fftRadix16Pass(data);      // in-place radix-16 pass
    twiddleFactorMul(data, tid, 1024, 0);

    // local shuffle using local memory
    localShuffle(data, sMemx, sMemy, tid, (((tid & 15) * 65) + (tid >> 4)));
    fftRadix16Pass(data);               // in-place radix-16 pass
    twiddleFactorMul(data, tid, 64, 4); // twiddle factor multiplication

    localShuffle(data, sMemx, sMemy, tid, (((tid >> 4) * 64) + (tid & 15)));

    // four radix-4 function calls
    fftRadix4Pass(data);      // radix-4 function number 1
    fftRadix4Pass(data + 4);  // radix-4 function number 2
    fftRadix4Pass(data + 8);  // radix-4 function number 3
    fftRadix4Pass(data + 12); // radix-4 function number 4

    // coalesced global writes
    globalStores(data, out, 64);
  }
)"

Eine vollständige Open-Source-Implementierung einer OpenCL-FFT finden Sie auf der Apple-Website.

C++ für OpenCL-Sprache

Im Jahr 2020 kündigte Khronos den Übergang zur Community-gesteuerten Programmiersprache C++ für OpenCL an, die Funktionen von C++17 in Kombination mit den traditionellen OpenCL-C-Funktionen bietet. Diese Sprache ermöglicht die Nutzung einer Vielzahl von Sprachfeatures von Standard-C++ bei gleichzeitiger Beibehaltung der Abwärtskompatibilität zu OpenCL C. Dies eröffnet den OpenCL-Kernelcode-Entwicklern einen reibungslosen Übergang zur C++-Funktionalität, da sie weiterhin den vertrauten Programmierfluss und sogar Tools wie sowie die Nutzung vorhandener Erweiterungen und Bibliotheken, die für OpenCL C verfügbar sind.

Die Sprachsemantik ist in der Dokumentation beschrieben, die in den Veröffentlichungen des OpenCL-Docs-Repositorys der Khronos-Gruppe veröffentlicht wurde, aber derzeit nicht von der Khronos-Gruppe ratifiziert wird. Die Sprache C++ für OpenCL ist nicht in einem eigenständigen Dokument dokumentiert und basiert auf der Spezifikation von C++ und OpenCL C. Der Open-Source- Compiler Clang unterstützt seit Release 9 C++ für OpenCL.

C++ für OpenCL wurde ursprünglich als Clang-Compiler-Erweiterung entwickelt und erschien in der Version 9. Da es eng mit OpenCL C gekoppelt war und keine Clang-spezifischen Funktionen enthielt, wurde seine Dokumentation im OpenCL-Docs-Repository von der Khronos Group zusammen mit den Quellen anderer Spezifikationen und Referenzkarten. Die erste offizielle Veröffentlichung dieses Dokuments, das C++ für OpenCL Version 1.0 beschreibt, wurde im Dezember 2020 veröffentlicht. C++ für OpenCL 1.0 enthält Funktionen von C++17 und ist abwärtskompatibel mit OpenCL C 2.0. Ein in Arbeit befindlicher Entwurf seiner Dokumentation ist auf der Khronos-Website zu finden.

Merkmale

C++ für OpenCL unterstützt die meisten Funktionen (syntaktisch und semantisch) von OpenCL C mit Ausnahme von verschachtelter Parallelität und Blöcken. Es gibt jedoch geringfügige Unterschiede bei einigen unterstützten Funktionen, die hauptsächlich auf Unterschiede in der Semantik zwischen C++ und C zurückzuführen sind. C++ ist beispielsweise bei den impliziten Typkonvertierungen strenger und unterstützt den einschränkenden Typqualifizierer nicht. Die folgenden C++-Features werden von C++ für OpenCL nicht unterstützt: virtuelle Funktionen, dynamic_cast- Operator, new / delete- Operatoren ohne Platzierung , Ausnahmen, Zeiger auf Memberfunktionen , Referenzen auf Funktionen, C++-Standardbibliotheken. C++ für OpenCL erweitert das Konzept separater Speicherbereiche ( Adressräume ) von OpenCL C auf C++-Features - funktionale Casts, Templates, Klassenmember, Referenzen, Lambda-Funktionen, Operatoren. Die meisten C++-Features sind für die Kernel-Funktionen nicht verfügbar, zB Überladen oder Templating, beliebiges Klassenlayout im Parametertyp.

Beispiel: komplexe Zahlenarithmetik

Der folgende Codeausschnitt veranschaulicht, wie Kernel mit komplexer Zahlenarithmetik in C++ für die OpenCL-Sprache mit bequemer Verwendung von C++-Funktionen implementiert werden können.

// Define a class Complex, that can perform complex number computations with
// various precision when different types for T are used - double, float, half.
template<typename T>
class complex_t {
T m_re; // Real component.
T m_im; // Imaginary component.

public:
complex_t(T re, T im): m_re{re}, m_im{im} {};
// Define operator for complex number multiplication.
complex_t operator*(const complex_t &other) const
{
  return {m_re * other.m_re - m_im * other.m_im,
           m_re * other.m_im + m_im * other.m_re};
}
int get_re() const { return m_re; }
int get_im() const { return m_im; }
};

// A helper function to compute multiplication over complex numbers read from
// the input buffer and to store the computed result into the output buffer.
template<typename T>
void compute_helper(__global T *in, __global T *out) {
  auto idx = get_global_id(0);    
  // Every work-item uses 4 consecutive items from the input buffer
  // - two for each complex number.
  auto offset = idx * 4;
  auto num1 = complex_t{in[offset], in[offset + 1]};
  auto num2 = complex_t{in[offset + 2], in[offset + 3]};
  // Perform complex number multiplication.
  auto res = num1 * num2;
  // Every work-item writes 2 consecutive items to the output buffer.
  out[idx * 2] = res.get_re();
  out[idx * 2 + 1] = res.get_im();
}

// This kernel is used for complex number multiplication in single precision.
__kernel void compute_sp(__global float *in, __global float *out) {
  compute_helper(in, out);
}

#ifdef cl_khr_fp16
// This kernel is used for complex number multiplication in half precision when
// it is supported by the device.
#pragma OPENCL EXTENSION cl_khr_fp16: enable
__kernel void compute_hp(__global half *in, __global half *out) {
  compute_helper(in, out); 
}
#endif

Werkzeug- und Ausführungsumgebung

Die Sprache C++ für OpenCL kann für dieselben Anwendungen oder Bibliotheken und auf dieselbe Weise wie die Sprache OpenCL C verwendet werden. Aufgrund der großen Vielfalt an C++-Sprachfeatures können in C++ für OpenCL geschriebene Anwendungen komplexe Funktionen bequemer ausdrücken als in OpenCL geschriebene Anwendungen. C und insbesondere das generische Programmierparadigma von C++ ist für Bibliotheksentwickler sehr attraktiv.

C++ für OpenCL-Quellen können von OpenCL-Treibern kompiliert werden, die die Erweiterung cl_ext_cxx_for_opencl unterstützen . Arm hat die Unterstützung für diese Erweiterung im Dezember 2020 angekündigt. Aufgrund der zunehmenden Komplexität der auf OpenCL-Geräten beschleunigten Algorithmen wird jedoch erwartet, dass mehr Anwendungen C++ für OpenCL-Kernel offline mit eigenständigen Compilern wie Clang in ausführbare Binärformate kompilieren oder portables Binärformat zB SPIR-V. Eine solche ausführbare Datei kann während der Ausführung von OpenCL-Anwendungen unter Verwendung einer dedizierten OpenCL-API geladen werden.

Binärdateien, die aus Quellen in C++ für OpenCL 1.0 kompiliert wurden, können auf OpenCL 2.0-konformen Geräten ausgeführt werden. Abhängig von den Sprachfeatures, die in solchen Kernelquellen verwendet werden, kann es auch auf Geräten ausgeführt werden, die frühere OpenCL-Versionen oder OpenCL 3.0 unterstützen.

Abgesehen von OpenCL-Treibern können Kernel, die in C++ für OpenCL geschrieben wurden, für die Ausführung auf Vulkan-Geräten mit dem clspv-Compiler und der clvk-Laufzeitschicht genauso wie OpenCL-C-Kernel kompiliert werden.

Beiträge

C++ für OpenCL ist eine offene Sprache, die von der Gemeinschaft der Mitwirkenden entwickelt wurde, die in ihrer Dokumentation aufgeführt sind. Neue Beiträge zur sprachsemantischen Definition oder zur Open-Source-Tooling-Unterstützung werden von allen Interessierten akzeptiert, sobald sie mit der Hauptdesignphilosophie übereinstimmen und von den erfahrenen Mitwirkenden überprüft und genehmigt wurden.

Geschichte

OpenCL wurde ursprünglich von Apple Inc. entwickelt , die Markenrechte hält , und in Zusammenarbeit mit technischen Teams von AMD , IBM , Qualcomm , Intel und Nvidia zu einem ersten Vorschlag weiterentwickelt . Apple hat diesen ersten Vorschlag der Khronos-Gruppe vorgelegt . Am 16. Juni 2008 wurde die Khronos Compute Working Group mit Vertretern von CPU-, GPU-, Embedded-Prozessor- und Softwareunternehmen gebildet. Diese Gruppe arbeitete fünf Monate lang daran, die technischen Details der Spezifikation für OpenCL 1.0 bis zum 18. November 2008 fertigzustellen. Diese technische Spezifikation wurde von den Khronos-Mitgliedern überprüft und am 8. Dezember 2008 zur Veröffentlichung freigegeben.

OpenCL 1.0

OpenCL 1.0 mit Mac OS X Snow Leopard am 28. August 2009 veröffentlicht. Laut einer Pressemitteilung von Apple:

Snow Leopard erweitert die Unterstützung für moderne Hardware mit Open Computing Language (OpenCL), die es jeder Anwendung ermöglicht, die riesigen Gigaflops an GPU-Rechenleistung zu nutzen, die bisher nur Grafikanwendungen zur Verfügung standen. OpenCL basiert auf der Programmiersprache C und wurde als offener Standard vorgeschlagen.

AMD hat sich entschieden, OpenCL anstelle des mittlerweile veralteten Close to Metal in seinem Stream-Framework zu unterstützen . RapidMind gab die Einführung von OpenCL unter seiner Entwicklungsplattform bekannt, um GPUs von mehreren Anbietern mit einer Schnittstelle zu unterstützen. Am 9. Dezember 2008 kündigte Nvidia seine Absicht an, sein GPU Computing Toolkit um die Spezifikation OpenCL 1.0 zu erweitern. Am 30. Oktober 2009 veröffentlichte IBM seine erste OpenCL-Implementierung als Teil der XL-Compiler .

Beschleunigung von Berechnungen mit Faktor 1000 sind mit OpenCL in Grafikkarten gegen normale CPU möglich. Einige wichtige Funktionen der nächsten Version von OpenCL sind in 1.0 optional, wie Operationen mit doppelter oder halber Genauigkeit.

OpenCL 1.1

OpenCL 1.1 wurde am 14. Juni 2010 von der Khronos Group ratifiziert und fügt bedeutende Funktionen für eine verbesserte Flexibilität, Funktionalität und Leistung der parallelen Programmierung hinzu, einschließlich:

  • Neue Datentypen einschließlich 3-Komponenten-Vektoren und zusätzliche Bildformate;
  • Handhabung von Befehlen von mehreren Host-Threads und Verarbeitung von Puffern über mehrere Geräte hinweg;
  • Operationen an Bereichen eines Puffers, einschließlich Lesen, Schreiben und Kopieren von rechteckigen 1D-, 2D- oder 3D-Bereichen;
  • Verbesserte Verwendung von Ereignissen, um die Befehlsausführung zu steuern und zu steuern;
  • Zusätzliche OpenCL-integrierte C-Funktionen wie Integer-Clamp, Shuffle und asynchrone Strided-Copys;
  • Verbesserte OpenGL-Interoperabilität durch effizientes Teilen von Bildern und Puffern durch die Verknüpfung von OpenCL- und OpenGL-Ereignissen.

OpenCL 1.2

Am 15. November 2011 kündigte die Khronos Group die OpenCL 1.2-Spezifikation an, die gegenüber den Vorgängerversionen erhebliche Funktionen in Bezug auf Leistung und Funktionen für die parallele Programmierung hinzufügte. Zu den bemerkenswertesten Funktionen gehören:

  • Gerätepartitionierung: die Möglichkeit, ein Gerät in Untergeräte aufzuteilen, sodass Arbeitsaufträge einzelnen Recheneinheiten zugewiesen werden können. Dies ist nützlich, um Bereiche des Geräts zu reservieren, um die Latenz für zeitkritische Aufgaben zu reduzieren.
  • Separates Kompilieren und Binden von Objekten: die Funktionalität zum Kompilieren von OpenCL in externe Bibliotheken zur Einbindung in andere Programme.
  • Verbesserte Bildunterstützung (optional): 1.2 fügt Unterstützung für 1D-Bilder und 1D/2D-Bild-Arrays hinzu. Darüber hinaus ermöglichen die OpenGL-Sharing-Erweiterungen jetzt die Verwendung von OpenGL 1D-Texturen und 1D/2D-Texturarrays zum Erstellen von OpenCL-Bildern.
  • Eingebaute Kernel: Benutzerdefinierte Geräte, die spezifische einzigartige Funktionen enthalten, werden jetzt enger in das OpenCL-Framework integriert. Kernel können aufgerufen werden, um spezielle oder nicht programmierbare Aspekte der zugrunde liegenden Hardware zu verwenden. Beispiele umfassen Videocodierung/-decodierung und digitale Signalprozessoren.
  • DirectX-Funktionalität: Die gemeinsame Nutzung von DX9-Medienoberflächen ermöglicht eine effiziente gemeinsame Nutzung zwischen OpenCL- und DX9- oder DXVA- Medienoberflächen. Ebenso ist für DX11 die nahtlose gemeinsame Nutzung zwischen OpenCL- und DX11-Oberflächen aktiviert.
  • Die Möglichkeit, IEEE 754- Konformität für Gleitkomma-Mathematik mit einfacher Genauigkeit zu erzwingen : OpenCL ermöglicht standardmäßig, dass die Versionen mit einfacher Genauigkeit der Divisions-, Kehrwert- und Quadratwurzeloperationen weniger genau sind als die korrekt gerundeten Werte, die IEEE 754 erfordert. Wenn der Programmierer das Befehlszeilenargument "-cl-fp32-correctly-rounded-divide-sqrt" an den Compiler übergibt, werden diese drei Operationen gemäß den Anforderungen von IEEE 754 berechnet, wenn die OpenCL-Implementierung dies unterstützt, und können nicht kompiliert werden, wenn die Die OpenCL-Implementierung unterstützt nicht die Berechnung dieser Operationen zu ihren korrekt gerundeten Werten, wie in der IEEE 754-Spezifikation definiert. Diese Fähigkeit wird durch die Fähigkeit ergänzt, die OpenCL-Implementierung abzufragen, um festzustellen, ob sie diese Operationen mit der Genauigkeit von IEEE 754 ausführen kann.

OpenCL 2.0

Am 18. November 2013 gab die Khronos Group die Ratifizierung und Veröffentlichung der finalisierten OpenCL 2.0-Spezifikation bekannt. Updates und Ergänzungen zu OpenCL 2.0 umfassen:

  • Gemeinsamer virtueller Speicher
  • Verschachtelte Parallelität
  • Generischer Adressraum
  • Bilder (optional, inkl. 3D-Bild)
  • C11 Atome
  • Rohre
  • Android installierbare Client-Treibererweiterung
  • halbe Genauigkeit erweitert mit optionaler cl_khr_fp16-Erweiterung
  • cl_double: IEEE 754 mit doppelter Genauigkeit (optional)

OpenCL 2.1

Die Ratifizierung und Veröffentlichung der vorläufigen OpenCL 2.1-Spezifikation wurde am 3. März 2015 auf der Game Developer Conference in San Francisco angekündigt. Es wurde am 16. November 2015 veröffentlicht. Es führte die OpenCL C++-Kernelsprache ein, die auf einer Teilmenge von C++14 basiert , während die Unterstützung für die bereits vorhandene OpenCL C-Kernelsprache beibehalten wurde. Vulkan und OpenCL 2.1 teilen sich SPIR-V als Zwischendarstellung, die es Hochsprachen-Frontends ermöglicht, ein gemeinsames Kompilierungsziel zu teilen. Zu den Aktualisierungen der OpenCL-API gehören:

  • Zusätzliche Untergruppenfunktionalität
  • Kopieren von Kernel-Objekten und -Zuständen
  • Geräte-Timer-Abfragen mit niedriger Latenz
  • Aufnahme von SPIR-V-Code nach Laufzeit
  • Hinweise zur Ausführungspriorität für Warteschlangen
  • Nullgrößen-Versendungen vom Host

AMD, ARM , Intel, HPC und YetiWare haben ihre Unterstützung für OpenCL 2.1 erklärt.

OpenCL 2.2

OpenCL 2.2 bringt die Kernelsprache OpenCL C++ in die Kernspezifikation ein, um die Produktivität der parallelen Programmierung erheblich zu steigern. Es wurde am 16. Mai 2017 veröffentlicht. Wartungsupdate veröffentlicht im Mai 2018 mit Bugfixes.

  • Die Kernelsprache OpenCL C++ ist eine statische Untermenge des C++14- Standards und umfasst Klassen, Vorlagen, Lambda-Ausdrücke, Funktionsüberladungen und viele andere Konstrukte für die generische und Meta-Programmierung.
  • Verwendet die neue Zwischensprache Khronos SPIR-V 1.1, die die Kernelsprache OpenCL C++ vollständig unterstützt.
  • OpenCL-Bibliotheksfunktionen können jetzt die Sprache C++ verwenden, um beim Zugriff auf Funktionen wie Atomics, Iteratoren, Images, Sampler, Pipes und integrierte Typen und Adressräume für Gerätewarteschlangen erhöhte Sicherheit und weniger undefiniertes Verhalten zu bieten.
  • Pipe-Speicher ist ein neuer geräteseitiger Typ in OpenCL 2.2, der für FPGA-Implementierungen nützlich ist, indem Konnektivitätsgröße und -typ zur Kompilierzeit bekannt gemacht werden, was eine effiziente gerätebezogene Kommunikation zwischen Kerneln ermöglicht.
  • OpenCL 2.2 enthält auch Funktionen zur verbesserten Optimierung des generierten Codes: Anwendungen können den Wert der Spezialisierungskonstante zur SPIR-V-Kompilierungszeit bereitstellen, eine neue Abfrage kann nicht-triviale Konstruktoren und Destruktoren von globalen Objekten im Programmbereich erkennen und Benutzer-Callbacks können gesetzt werden zum Zeitpunkt der Programmfreigabe.
  • Läuft auf jeder OpenCL 2.0-fähigen Hardware (nur ein Treiber-Update erforderlich).

OpenCL 3.0

Die OpenCL 3.0-Spezifikation wurde am 30. September 2020 veröffentlicht, nachdem sie seit April 2020 in der Vorschau war. Die OpenCL 1.2-Funktionalität wurde zu einer obligatorischen Basis, während alle OpenCL 2.x- und OpenCL 3.0-Funktionen optional gemacht wurden. Die Spezifikation behält die OpenCL C-Sprache bei und setzt die OpenCL C++-Kernelsprache ab und ersetzt sie durch die C++ für OpenCL-Sprache, die auf einem Clang / LLVM- Compiler basiert, der eine Teilmenge von C++17- und SPIR-V- Zwischencode implementiert . Version 3.0.7 von C++ für OpenCL mit einigen Khronos openCL-Erweiterungen wurde auf der IWOCL 21 vorgestellt.

Fahrplan

Der International Workshop on OpenCL (IWOCL) der Khronos Group

Bei der Veröffentlichung von OpenCL 2.2 kündigte die Khronos Group an, dass OpenCL nach Möglichkeit mit Vulkan konvergieren wird , um die Flexibilität der OpenCL-Softwarebereitstellung über beide APIs zu ermöglichen. Dies wurde jetzt von Adobes Premiere Rush demonstriert, der den Open-Source-Compiler clspv verwendet, um erhebliche Mengen an OpenCL-C-Kernelcode zu kompilieren, um auf einer Vulkan-Laufzeit für die Bereitstellung auf Android ausgeführt zu werden. OpenCL hat eine von Vulkan unabhängige zukunftsweisende Roadmap, wobei 'OpenCL Next' in der Entwicklung ist und die Veröffentlichung im Jahr 2020 angestrebt wird. OpenCL Next kann Erweiterungen wie Vulkan / OpenCL Interop, Scratch-Pad Memory Management, Extended Subgroups, SPIR-V 1.4 Ingestion und . integrieren SPIR-V Erweiterte Debug-Informationen. OpenCL erwägt auch Vulkan-ähnliche Loader und Layer und ein "Flexible Profile" für Bereitstellungsflexibilität auf mehreren Beschleunigertypen.

Open-Source-Implementierungen

clinfo, ein Befehlszeilentool zum Anzeigen von OpenCL-Informationen

OpenCL besteht aus einem Satz von Headern und einem gemeinsamen Objekt , das zur Laufzeit geladen wird. Ein installierbarer Client-Treiber (ICD) muss auf der Plattform für jede Anbieterklasse installiert werden, die die Laufzeitumgebung unterstützen muss. Das heißt, um beispielsweise Nvidia-Geräte auf einer Linux-Plattform zu unterstützen, müsste die Nvidia-ICD so installiert werden, dass die OpenCL-Laufzeit (der ICD-Loader) den ICD für den Hersteller finden und die Aufrufe entsprechend umleiten kann . Der Standard-OpenCL-Header wird von der Verbraucheranwendung verwendet; Aufrufe an jede Funktion werden dann von der OpenCL-Laufzeit über den ICD an den entsprechenden Treiber weitergeleitet. Jeder Hersteller muss jeden OpenCL-Aufruf in seinem Treiber implementieren.

Die Apple-, Nvidia-, RapidMind- und Gallium3D- Implementierungen von OpenCL basieren alle auf der LLVM- Compiler-Technologie und verwenden den Clang- Compiler als Frontend.

MESA-Gallium-Rechner
Eine Implementierung von OpenCL (aktuell 1.1 unvollständig, meist gemacht AMD Radeon GCN ) für eine Reihe von Plattformen wird im Rahmen des Gallium Compute Project gepflegt, das auf der Arbeit des Mesa-Projekts aufbaut , um mehrere Plattformen zu unterstützen. Früher war dies als CLOVER bekannt., aktuelle Entwicklung: hauptsächlich Unterstützung für den Betrieb unvollständiger Frameworks mit aktuellem LLVM und CLANG, einige neue Funktionen wie fp16 in 17.3, Target komplett OpenCL 1.0, 1.1 und 1.2 für AMD und Nvidia. New Basic Development wird von Red Hat mit SPIR-V auch für Clover durchgeführt. Neues Ziel ist modulares OpenCL 3.0 mit voller Unterstützung von OpenCL 1.2. Der aktuelle Status ist in Mesamatrix verfügbar. Bildträger stehen hier im Fokus der Entwicklung.
BEIGNET
Eine Implementierung von Intel für seine Ivy Bridge+ -Hardware wurde 2013 veröffentlicht. Diese Software von Intels China-Team hat Kritik von Entwicklern bei AMD und Red Hat sowie Michael Larabel von Phoronix auf sich gezogen . Die aktuelle Version 1.3.2 unterstützt OpenCL 1.2 komplett (Ivy Bridge und höher) und OpenCL 2.0 optional für Skylake und neuer. Unterstützung für Android wurde zu Beignet hinzugefügt., tatsächliche Entwicklungsziele: nur Unterstützung für 1.2 und 2.0, Weg zu OpenCL 2.1, 2.2, 3.0 ist auf NEO gegangen.
NEO
Eine Implementierung von Intel für Gen. 8 Broadwell + Gen. 9 Hardware, die 2018 veröffentlicht wurde. Dieser Treiber ersetzt die Beignet-Implementierung für unterstützte Plattformen (nicht älter 6. Gen bis Haswell). NEO bietet OpenCL 2.1-Unterstützung auf Core-Plattformen und OpenCL 1.2 auf Atom-Plattformen. Aktuell werden 2020 auch Graphic Gen 11 Ice Lake und Gen 12 Tiger Lake unterstützt. Neues OpenCL 3.0 ist für Alder Lake, Tiger Lake bis Broadwell mit Version 20.41+ verfügbar. Es enthält jetzt optional OpenCL 2.0, 2.1 Features Complete und einige von 2.2.
ROCm
ROCm (Radeon Open Compute) wurde als Teil von AMDs GPUOpen entwickelt und ist ein Open-Source-Linux-Projekt, das auf OpenCL 1.2 mit Sprachunterstützung für 2.0 basiert. Das System ist mit allen modernen AMD CPUs und APUs (eigentlich teilweise GFX 7, GFX 8 und 9) sowie Intel Gen7.5+ CPUs (nur mit PCI 3.0) kompatibel. Mit Version 1.9 wird die Unterstützung in einigen Punkten experimentell auf Hardware mit PCIe 2.0 und ohne Atomics erweitert. Ein Überblick über die aktuelle Arbeit wird auf XDC2018 durchgeführt. ROCm Version 2.0 unterstützt Full OpenCL 2.0, aber einige Fehler und Einschränkungen stehen auf der Todo-Liste. Version 3.3 verbessert sich im Detail. Version 3.5 unterstützt OpenCL 2.2. Version 3.10 war mit Verbesserungen und neuen APIs ausgestattet. Angekündigt auf der SC20 ist ROCm 4.0 mit Unterstützung von AMD Compute Card Instinct MI 100. Die aktuelle Dokumentation von 4.3.1 ist auf github verfügbar. OpenCL 3.0 ist in Arbeit.
POCL
Eine portable Implementierung, die CPUs und einige GPUs (über CUDA und HSA ) unterstützt. Aufbauend auf Clang und LLVM . Mit Version 1.0 wurde OpenCL 1.2 zusammen mit einigen 2.x-Features fast vollständig implementiert. Version 1.2 ist mit LLVM/CLANG 6.0, 7.0 und vollständiger OpenCL 1.2-Unterstützung mit allen geschlossenen Tickets in Milestone 1.2. OpenCL 2.0 ist fast vollständig implementiert. Version 1.3 unterstützt Mac OS X. Version 1.4 umfasst Unterstützung für LLVM 8.0 und 9.0. Version 1.5 implementiert LLVM/Clang 10-Unterstützung. Version 1.6 implementiert LLVM/Clang 11-Unterstützung und CUDA-Beschleunigung. Tatsächliche Ziele sind vollständiges OpenCL 2.x, OpenCL 3.0 und Leistungsverbesserungen. POCL 1.6 ist mit manueller Optimierung auf dem gleichen Niveau der Intel-Rechenlaufzeit. Version 1.7 implementiert LLVM/Clang 12-Unterstützung und einige neue OpenCL 3.0-Funktionen.
Kleeblatt
Eine Portierung von Mesa Clover für ARM mit voller Unterstützung von OpenCL 1.2, keine aktuelle Entwicklung für 2.0.
KostenlosOCL
Eine CPU-fokussierte Implementierung von OpenCL 1.2, die einen externen Compiler implementiert, um eine zuverlässigere Plattform zu schaffen, keine tatsächliche Entwicklung.
MOCL
Eine auf POCL basierende OpenCL-Implementierung der NUDT-Forscher für Matrix-2000 wurde 2018 veröffentlicht. Die Matrix-2000-Architektur soll die Intel Xeon Phi-Beschleuniger des TianHe-2-Supercomputers ersetzen. Dieses Programmier-Framework baut auf LLVM v5.0 auf und verwendet auch einige Code-Stücke von POCL. Um das Hardware-Potenzial auszuschöpfen, verwendet die Geräte-Laufzeit eine Push-basierte Task-Dispatching-Strategie und die Leistung der Kernel-Atomics wird deutlich verbessert. Dieses Framework wurde auf dem TH-2A-System bereitgestellt und ist der Öffentlichkeit leicht zugänglich. Als nächstes wird ein Teil der Software portiert, um POCL zu verbessern.
VC4CL
Eine OpenCL 1.2-Implementierung für den VideoCore IV (BCM2763)-Prozessor, der im Raspberry Pi vor seinem Modell 4 verwendet wurde.

Anbieterimplementierungen

Zeitleiste der Anbieterimplementierungen

  • Juni 2008: Während der WWDC-Konferenz von Apple wurde den Teilnehmern eine frühe Beta- Version von Mac OS X Snow Leopard zur Verfügung gestellt, darunter die erste Beta-Implementierung von OpenCL, etwa 6 Monate vor der Ratifizierung der endgültigen Version 1.0-Spezifikation Ende 2008. Sie zeigten auch zwei Demos. Einer war ein Raster von 8x8-Bildschirmen, die jeweils den Bildschirm einer emulierten Apple II-Maschine anzeigten – insgesamt 64 unabhängige Instanzen, auf denen jeweils ein berühmtes Karate-Spiel lief. Dies zeigte Aufgabenparallelität auf der CPU. Die andere Demo war eine N-Body-Simulation, die auf der GPU eines Mac Pro lief, eine datenparallele Aufgabe.
  • 10. Dezember 2008: AMD und Nvidia veranstalteten die erste öffentliche OpenCL-Demonstration, eine 75-minütige Präsentation auf der SIGGRAPH Asia 2008. AMD zeigte eine CPU-beschleunigte OpenCL-Demo, die die Skalierbarkeit von OpenCL auf einem oder mehreren Kernen erläuterte, während Nvidia eine GPU-beschleunigte zeigte Demo.
  • 16. März 2009: Auf der 4. Multicore Expo kündigte Imagination Technologies den PowerVR SGX543MP an, die erste GPU dieses Unternehmens mit OpenCL-Unterstützung.
  • 26. März 2009: Auf der GDC 2009 demonstrierten AMD und Havok die erste funktionierende Implementierung für die OpenCL-Beschleunigung von Havok Cloth auf einer GPU der AMD Radeon HD 4000-Serie .
  • 20. April 2009: Nvidia kündigt die Veröffentlichung seines OpenCL-Treibers und des SDK für Entwickler an, die an seinem OpenCL-Early-Access-Programm teilnehmen.
  • 5. August 2009: AMD hat im Rahmen seines ATI Stream SDK v2.0 Beta-Programms die ersten Entwicklungstools für seine OpenCL-Plattform vorgestellt .
  • 28. August 2009: Apple veröffentlicht Mac OS X Snow Leopard , das eine vollständige Implementierung von OpenCL enthält.
  • 28. September 2009: Nvidia veröffentlicht seine eigenen OpenCL-Treiber und die SDK-Implementierung.
  • 13. Oktober 2009: AMD hat die vierte Beta des ATI Stream SDK 2.0 veröffentlicht, die eine vollständige OpenCL-Implementierung sowohl auf R700 / R800 GPUs als auch auf SSE3- fähigen CPUs bietet . Das SDK ist sowohl für Linux als auch für Windows verfügbar.
  • 26. November 2009: Nvidia veröffentlicht Treiber für OpenCL 1.0 (Rev 48).
  • 27. Oktober 2009: S3 veröffentlicht sein erstes Produkt, das natives OpenCL 1.0 unterstützt – den eingebetteten Grafikprozessor Chrome 5400E.
  • 10. Dezember 2009: VIA veröffentlicht sein erstes Produkt, das OpenCL 1.0 unterstützt – ChromotionHD 2.0 Videoprozessor im VN1000 Chipsatz enthalten.
  • 21. Dezember 2009: AMD hat die Produktionsversion des ATI Stream SDK 2.0 veröffentlicht, die OpenCL 1.0-Unterstützung für R800- GPUs und Beta-Unterstützung für R700- GPUs bietet .
  • 1. Juni 2010: ZiiLABS veröffentlicht Details seiner ersten OpenCL-Implementierung für den ZMS-Prozessor für Handheld-, Embedded- und Digital Home-Produkte.
  • 30. Juni 2010: IBM hat eine vollständig konforme Version von OpenCL 1.0 veröffentlicht.
  • 13. September 2010: Intel veröffentlicht Details seiner ersten OpenCL-Implementierung für die Sandy-Bridge-Chiparchitektur. Sandy Bridge wird Intels neueste Grafikchip-Technologie direkt in die Zentraleinheit integrieren.
  • 15. November 2010: Wolfram Research veröffentlicht Mathematica 8 mit OpenCLLink- Paket.
  • 3. März 2011: Die Khronos Group gibt die Bildung der WebCL- Arbeitsgruppe bekannt, um die Definition einer JavaScript- Bindung an OpenCL zu untersuchen. Dadurch besteht die Möglichkeit, die parallele Verarbeitung von GPU und Multi-Core-CPU über einen Webbrowser zu nutzen .
  • 31. März 2011: IBM hat eine vollständig konforme Version von OpenCL 1.1 veröffentlicht.
  • 25. April 2011: IBM veröffentlicht OpenCL Common Runtime v0.1 für Linux auf der x86-Architektur.
  • 4. Mai 2011: Nokia Research veröffentlicht eine Open-Source-WebCL-Erweiterung für den Firefox -Webbrowser, die eine JavaScript-Bindung an OpenCL bereitstellt.
  • 1. Juli 2011: Samsung Electronics veröffentlicht eine Open-Source-Prototypimplementierung von WebCL für WebKit, die eine JavaScript-Bindung an OpenCL bereitstellt.
  • 8. August 2011: AMD veröffentlicht das OpenCL-gesteuerte AMD Accelerated Parallel Processing (APP) Software Development Kit (SDK) v2.5, das das ATI Stream SDK als Technologie und Konzept ersetzt.
  • 12. Dezember 2011: AMD hat AMD APP SDK v2.6 veröffentlicht, das eine Vorschau von OpenCL 1.2 enthält.
  • 27. Februar 2012: Die Portland Group veröffentlicht den PGI OpenCL-Compiler für Multi-Core- ARM- CPUs.
  • 17. April 2012: Khronos veröffentlicht einen WebCL-Arbeitsentwurf.
  • 6. Mai 2013: Altera veröffentlicht das Altera SDK für OpenCL, Version 13.0. Es ist OpenCL 1.0 konform.
  • 18. November 2013: Khronos gibt bekannt, dass die Spezifikation für OpenCL 2.0 fertiggestellt ist.
  • 19. März 2014: Khronos veröffentlicht die WebCL 1.0-Spezifikation
  • 29. August 2014: Intel veröffentlicht HD Graphics 5300-Treiber, der OpenCL 2.0 unterstützt.
  • 25. September 2014: AMD veröffentlicht Catalyst 14.41 RC1, das einen OpenCL 2.0-Treiber enthält.
  • 14. Januar 2015: Xilinx Inc. kündigt SDAccel-Entwicklungsumgebung für OpenCL, C und C++ an, erreicht Khronos-Konformität
  • 13. April 2015: Nvidia veröffentlicht den WHQL-Treiber v350.12, der OpenCL 1.2-Unterstützung für GPUs enthält, die auf Kepler- oder späteren Architekturen basieren. Driver 340+ unterstützt OpenCL 1.1 für Tesla und Fermi.
  • 26. August 2015: AMD hat AMD APP SDK v3.0 veröffentlicht, das vollständige Unterstützung von OpenCL 2.0 und Beispielcodierung enthält.
  • 16. November 2015: Khronos gibt bekannt, dass die Spezifikation für OpenCL 2.1 fertiggestellt ist.
  • 18. April 2016: Khronos gibt bekannt, dass die Spezifikation für OpenCL 2.2 vorläufig finalisiert wurde.
  • 3. November 2016 Intel-Unterstützung für Gen7+ von OpenCL 2.1 in SDK 2016 r3
  • 17. Februar 2017: Nvidia beginnt mit der Evaluierungsunterstützung von OpenCL 2.0 mit dem Treiber 378.66.
  • 16. Mai 2017: Khronos gab bekannt, dass die Spezifikation für OpenCL 2.2 mit SPIR-V 1.2 finalisiert wurde.
  • 14. Mai 2018: Khronos kündigte Maintenance Update für OpenCL 2.2 mit Bugfix und einheitlichen Headern an.
  • 27. April 2020: Khronos kündigt vorläufige Version von OpenCL 3.0 an
  • 1. Juni 2020: Intel Neo Runtime mit OpenCL 3.0 für neuen Tiger Lake
  • 3. Juni 2020: AMD kündigt RocM 3.5 mit OpenCL 2.2-Unterstützung an
  • 30. September 2020: Khronos gibt bekannt, dass die Spezifikationen für OpenCL 3.0 finalisiert sind (CTS ebenfalls verfügbar).
  • 16. Oktober 2020: Intel kündigt mit Neo 20.41 Unterstützung für OpenCL 3.0 an (beinhaltet hauptsächlich optionales OpenCL 2.x)
  • 6. April 2021: Nvidia unterstützt OpenCL 3.0 für Ampere. Maxwell und neuere GPUs unterstützen auch OpenCL 3.0 mit Nvidia-Treiber 465+.

Geräte

Ab 2016 läuft OpenCL auf Grafikprozessoren , CPUs mit SIMD- Befehlen, FPGAs , Movidius Myriad 2 , Adapteva Epiphany und DSPs .

Khronos Konformitätstest-Suite

Um offiziell konform zu sein, muss eine Implementierung die Khronos Conformance Test Suite (CTS) bestehen, wobei die Ergebnisse beim Khronos Adopters Program eingereicht werden. Der Khronos CTS-Code für alle OpenCL-Versionen ist seit 2017 in Open Source verfügbar.

Konforme Produkte

Die Khronos Group unterhält eine erweiterte Liste von OpenCL-konformen Produkten.

Übersicht über OpenCL-konforme Produkte
AMD SDKs (unterstützt OpenCL- CPU und beschleunigte Prozessoreinheiten ), (GPU: Terascale 1: OpenCL 1.1, Terascale 2: 1.2, GCN 1: 1.2+, GCN 2+: 2.0+) X86 + SSE2 (oder höher) kompatible CPUs 64-Bit & 32-Bit , Linux 2.6 PC, Windows Vista/7/8.x/10 PC AMD Fusion E-350, E-240, C-50, C-30 mit HD 6310/HD 6250 AMD Radeon /Mobility HD 6800, HD 5x00 Serie GPU, iGPU HD 6310/HD 6250, HD 7xxx, HD 8xxx, R2xx, R3xx, RX 4xx, RX 5xx, Vega Serie GPU der AMD FirePro Vx800-Serie und höher, Radeon Pro
Intel SDK für OpenCL Applications 2013 (unterstützt Intel Core Prozessoren und Intel HD Graphics 4000/2500) 2017 R2 mit OpenCL 2.1 (Gen7+), SDK 2019 entfernt OpenCL 2.1, Aktuelles SDK 2020 Update 3 Intel- CPUs mit SSE 4.1-, SSE 4.2- oder AVX- Unterstützung. Microsoft Windows , Linux Intel Core i7 , i5 , i3 ; Intel Core i7/5/3 der 2. Generation, Intel Core-Prozessoren der 3. Generation mit Intel HD Graphics 4000/2500 und neuer Intel Core 2 Solo, Duo Quad, Extreme und neuer Intel Xeon 7x00,5x00,3x00 (Core-basiert) und neuer
IBM Server mit OpenCL Development Kit für Linux on Power auf Power VSX IBM Power 775 ( PERCS ), 750 IBM BladeCenter PS70x Express IBM BladeCenter JS2x, JS43 IBM BladeCenter QS22
IBM OpenCL Common Runtime (OCR)

X86 + SSE2 (oder höher) kompatible CPUs 64-Bit & 32-Bit; Linux 2.6 PC AMD Fusion , Nvidia Ion und Intel Core i7, i5, i3; Intel Core i7/5/3 . der 2. Generation AMD Radeon, Nvidia GeForce und Intel Core 2 Solo, Duo, Quad, Extreme ATI FirePro, Nvidia Quadro und Intel Xeon 7x00,5x00,3x00 (Core-basiert)
Nvidia OpenCL Treiber und Tools , Chips: Tesla, Fermi : OpenCL 1.1 (Treiber 340+), Kepler, Maxwell, Pascal, Volta, Turing: OpenCL 1.2 (Treiber 370+), OpenCL 2.0 Beta (378.66), OpenCL 3.0: Maxwell to Ampere (Treiber 465+) Nvidia Tesla C/D/S Nvidia GeForce GTS/GT/GTX, Nvidia Ion Nvidia Quadro FX/NVX/Plex, Quadro, Quadro K, Quadro M, Quadro P, Quadro mit Volta, Quadro RTX mit Turing, Ampere

Alle standardkonformen Implementierungen können mit einem der clinfo-Tools abgefragt werden (es gibt mehrere Tools mit gleichem Namen und ähnlichem Funktionsumfang).

Versionsunterstützung

Zu den Produkten und deren Version der OpenCL-Unterstützung gehören:

OpenCL 3.0-Unterstützung

Alle Hardware mit OpenCL 1.2+ möglich, OpenCL 2.x nur optional, Khronos Test Suite verfügbar seit 2020-10

  • (2020) Intel NEO Compute: 20.41+ für Gen 12 Tiger Lake bis Broadwell (einschließlich vollständiger 2.0- und 2.1-Unterstützung und Teile von 2.2)
  • (2020) Intel Prozessoren der 6., 7., 8., 9., 10., 11. Generation ( Skylake , Kaby Lake , Coffee Lake , Comet Lake , Ice Lake , Tiger Lake ) mit dem neuesten Intel Windows-Grafiktreiber
  • (2021) Intel Prozessoren der 11., 12. Generation ( Rocket Lake , Alder Lake ) mit dem neuesten Intel Windows-Grafiktreiber
  • (2021) Nvidia Maxwell , Pascal , Volta , Turing und Ampere mit Nvidia Grafiktreiber 465+

OpenCL 2.2-Unterstützung

Noch keine : Khronos Test Suite ready, mit Driver Update alle Hardware mit 2.0 und 2.1 Support möglich

  • Intel NEO Compute: In Arbeit für aktuelle Produkte
  • ROCm: Version 3.5+ meistens

OpenCL 2.1-Unterstützung

  • (2018+) Unterstützung rückportiert auf Intel-Prozessoren der 5. und 6. Generation ( Broadwell , Skylake )
  • (2017+) Intel 7., 8., 9., 10. Generation Prozessoren ( Kaby Lake , Coffee Lake , Comet Lake , Ice Lake )
  • Khronos: mit Driver Update alle Hardware mit 2.0 Unterstützung möglich

OpenCL 2.0-Unterstützung

  • (2011+) AMD GCN GPUs (HD 7700+/HD 8000/Rx 200/Rx 300/Rx 400/Rx 500/Rx 5000-Serie), einige GCN 1st Gen nur 1.2 mit einigen Erweiterungen
  • (2013+) AMD GCN APUs ( Jaguar , Steamroller , Puma , Bagger & Zen- basiert)
  • (2014+) Intel Prozessoren der 5. und 6. Generation ( Broadwell , Skylake )
  • (2015+) Qualcomm Adreno 5xx-Serie
  • (2018+) Qualcomm Adreno 6xx-Serie
  • (2017+) ARM Mali (Bifrost) G51 und G71 in Android 7.1 und Linux
  • (2018+) ARM Mali (Bifrost) G31, G52, G72 und G76
  • (2017+) unvollständige Evaluierungsunterstützung: Nvidia Kepler , Maxwell , Pascal , Volta und Turing GPUs (GeForce 600, 700, 800, 900 & 10-Serie, Quadro K-, M- & P-Serie, Tesla K-, M- & P-Serie) mit Treiberversion 378.66+

OpenCL 1.2-Unterstützung

  • (2011+) für einige AMD GCN 1st Gen einige OpenCL 2.0 Features heute nicht möglich, aber viel mehr Erweiterungen als Terascale
  • (2009+) AMD TeraScale 2 & 3 GPUs (RV8xx, RV9xx in HD 5000, 6000 & 7000 Serie)
  • (2011+) AMD TeraScale APUs ( K10 , Bobcat & Piledriver- basiert)
  • (2012+) Nvidia Kepler, Maxwell, Pascal, Volta und Turing GPUs (GeForce 600, 700, 800, 900, 10, 16, 20 Serie, Quadro K-, M- & P-Serie, Tesla K-, M- & P-Serie)
  • (2012+) Intel Prozessoren der 3. und 4. Generation ( Ivy Bridge , Haswell )
  • (2013+) Qualcomm Adreno 4xx-Serie
  • (2013+) ARM Mali Midgard 3. Generation (T760)
  • (2015+) ARM Mali Midgard 4. Generation (T8xx)

OpenCL 1.1-Unterstützung

  • (2008+) einige AMD TeraScale 1 GPUs (RV7xx in HD4000-Serie)
  • (2008+) Nvidia Tesla, Fermi GPUs (GeForce 8, 9, 100, 200, 300, 400, 500-Serie, Quadro-Serie oder Tesla-Serie mit Tesla oder Fermi GPU)
  • (2011+) Qualcomm Adreno 3xx-Serie
  • (2012+) ARM Mali Midgard 1. und 2. Generation (T-6xx, T720)

OpenCL 1.0-Unterstützung

  • meist auf 1.1 und 1.2 aktualisiert nach dem ersten Treiber nur für 1.0

Portabilität, Leistung und Alternativen

Ein Schlüsselmerkmal von OpenCL ist die Portabilität über sein abstrahiertes Speicher- und Ausführungsmodell , und der Programmierer ist nicht in der Lage, hardwarespezifische Technologien wie Inline Parallel Thread Execution (PTX) für Nvidia-GPUs direkt zu verwenden, es sei denn, er ist bereit, auf direkte Portabilität zu verzichten auf anderen Plattformen. Es ist möglich, jeden OpenCL-Kernel auf jeder konformen Implementierung auszuführen.

Die Leistung des Kernels ist jedoch nicht unbedingt plattformübergreifend portierbar. Bestehende Implementierungen haben sich jedoch als konkurrenzfähig erwiesen, wenn der Kernel-Code richtig abgestimmt ist, und Auto-Tuning wurde als Lösung für das Leistungsportabilitätsproblem vorgeschlagen, was zu "akzeptablen Leistungsniveaus" in experimentellen linearen Algebra-Kerneln führt. Die Portabilität einer gesamten Anwendung mit mehreren Kerneln mit unterschiedlichem Verhalten wurde ebenfalls untersucht und zeigt, dass die Portabilität nur begrenzte Kompromisse erfordert.

Eine Studie der Universität Delft aus dem Jahr 2011, die CUDA- Programme und ihre einfache Übersetzung in OpenCL C verglich, ergab, dass CUDA OpenCL bei der Nvidia-Implementierung um höchstens 30 % übertrifft. Die Forscher stellten fest, dass ihr Vergleich durch manuelle Optimierungen auf die OpenCL-Programme gerechter werden könnte. In diesem Fall gab es "keinen Grund für OpenCL, eine schlechtere Leistung als CUDA zu erzielen". Die Leistungsunterschiede sind hauptsächlich auf Unterschiede im Programmiermodell (insbesondere im Speichermodell) und auf NVIDIAs Compiler-Optimierungen für CUDA im Vergleich zu denen für OpenCL zurückzuführen.

Eine andere Studie von D-Wave Systems Inc. ergab, dass „die Leistung des OpenCL-Kernels zwischen etwa 13 % und 63 % langsamer ist und die End-to-End-Zeit zwischen etwa 16 % und 67 % langsamer ist“ als die Leistung von CUDA.

Die Tatsache, dass OpenCL die Aufteilung von Arbeitslasten durch CPU und GPU ermöglicht und dieselben Programme ausführt, bedeutet, dass Programmierer beide ausnutzen können, indem sie die Arbeit auf die Geräte aufteilen. Dies führt zu dem Problem der Entscheidung, wie die Arbeit aufgeteilt werden soll, da die relativen Geschwindigkeiten der Operationen zwischen den Geräten unterschiedlich sind. Maschinelles Lernen wurde vorgeschlagen, um dieses Problem zu lösen: Grewe und O'Boyle beschreiben ein System von Support-Vektor-Maschinen, die auf Kompilierzeit-Features von Programmen trainiert wurden, die das Problem der Gerätepartitionierung statisch entscheiden können, ohne die Programme tatsächlich auszuführen, um ihre Leistung zu messen.

Im Vergleich aktueller Grafikkarten der AMD RDNA 2 und Nvidia RTX Serie gibt es ein unentschiedenes Ergebnis von OpenCL-Tests. Mögliche Leistungssteigerungen durch den Einsatz von Nvidia CUDA oder OptiX wurden nicht getestet.

Siehe auch

Verweise

Externe Links