Original author(s) | Apple Inc. |
---|---|
Developer(s) | Khronos Group |
Initial release | August 28, 2009 |
Stable release | 3.0[1]
/ September 30, 2020 |
Written in | C with C++ bindings |
Operating system | Android (vendor dependent),[2]FreeBSD,[3]Linux, macOS, Windows |
Platform | ARMv7, ARMv8,[4]Cell, IA-32, POWER, x86-64 |
Type | Heterogeneous computing API |
License | OpenCL specification license |
Website | www |
Paradigm | Imperative (procedural), structured, (C++ only) object-oriented, generic programming |
---|---|
Family | C |
Stable release | |
Typing discipline | Static, weak, manifest, nominal |
Implementation language | Implementation specific |
Filename extensions | .cl .clcpp |
Website | www |
Major implementations | |
AMD, Apple, freeocl, Gallium Compute, IBM, Intel Beignet, Intel SDK, Texas Instruments, Nvidia, POCL, Arm | |
Influenced by | |
C99, CUDA, C++14, C++17 |
OpenCL (Open Computing Language) is a framework for writing programs that execute across heterogeneous platforms consisting of central processing units (CPUs), graphics processing units (GPUs), digital signal processors (DSPs), field-programmable gate arrays (FPGAs) and other processors or hardware accelerators. OpenCL specifies programming languages (based on C99, C++14 and C++17) for programming these devices and application programming interfaces (APIs) to control the platform and execute programs on the compute devices. OpenCL provides a standard interface for parallel computing using task- and data-based parallelism.
OpenCL is an open standard maintained by the non-profit technology consortium Khronos Group. Conformant implementations are available from Altera, AMD, Apple (OpenCL along with OpenGL is deprecated for Apple hardware, in favor of Metal 2[8]), ARM, Creative, IBM, Imagination, Intel, Nvidia, Qualcomm, Samsung, Vivante, Xilinx, and ZiiLABS.[9][10]
OpenCL views a computing system as consisting of a number of compute devices, which might be central processing units (CPUs) or "accelerators" such as graphics processing units (GPUs), attached to a host processor (a CPU). It defines a C-like language for writing programs. Functions executed on an OpenCL device are called "kernels".[11]:17 A single compute device typically consists of several compute units, which in turn comprise multiple processing elements (PEs). A single kernel execution can run on all or many of the PEs in parallel. How a compute device is subdivided into compute units and PEs is up to the vendor; a compute unit can be thought of as a "core", but the notion of core is hard to define across all the types of devices supported by OpenCL (or even within the category of "CPUs"),[12]:49–50 and the number of compute units may not correspond to the number of cores claimed in vendors' marketing literature (which may actually be counting SIMD lanes).[13]
In addition to its C-like programming language, OpenCL defines an application programming interface (API) that allows programs running on the host to launch kernels on the compute devices and manage device memory, which is (at least conceptually) separate from host memory. Programs in the OpenCL language are intended to be compiled at run-time, so that OpenCL-using applications are portable between implementations for various host devices.[14] The OpenCL standard defines host APIs for C and C++; third-party APIs exist for other programming languages and platforms such as Python,[15]Java, Perl[16] and .NET.[12]:15 An implementation of the OpenCL standard consists of a library that implements the API for C and C++, and an OpenCL C compiler for the compute device(s) targeted.
In order to open the OpenCL programming model to other languages or to protect the kernel source from inspection, the Standard Portable Intermediate Representation (SPIR)[17] can be used as a target-independent way to ship kernels between a front-end compiler and the OpenCL back-end.
More recently Khronos Group has ratified SYCL,[18] a higher-level programming model for OpenCL as a single-source DSEL based on pure C++17 to improve programming productivity. In addition to that C++ features can also be used when implementing compute kernel sources in C++ for OpenCL language.[19]
OpenCL defines a four-level memory hierarchy for the compute device:[14]
Not every device needs to implement each level of this hierarchy in hardware. Consistency between the various levels in the hierarchy is relaxed, and only enforced by explicit synchronization constructs, notably barriers.
Devices may or may not share memory with the host CPU.[14] The host API provides handles on device memory buffers and functions to transfer data back and forth between host and devices.
The programming language that is used to write compute kernels is called kernel language. OpenCL adopts C/C++-based languages to specify the kernel computations performed on the device with some restrictions and additions to facilitate efficient mapping to the heterogeneous hardware resources of accelerators. Traditionally OpenCL C was used to program the accelarators in OpenCL standard, later C++ for OpenCL kernel language was developed that inherited all functionality from OpenCL C but allowed to use C++ features in the kernel sources.
OpenCL C[20] is a C99-based language dialect adapted to fit the device model in OpenCL. Memory buffers reside in specific levels of the memory hierarchy, and pointers are annotated with the region qualifiers __global, __local, __constant, and __private, reflecting this. Instead of a device program having a main function, OpenCL C functions are marked __kernel to signal that they are entry points into the program to be called from the host program. Function pointers, bit fields and variable-length arrays are omitted, and recursion is forbidden.[21] The C standard library is replaced by a custom set of standard functions, geared toward math programming.
OpenCL C is extended to facilitate use of parallelism with vector types and operations, synchronization, and functions to work with work-items and work-groups.[21] In particular, besides scalar types such as float and double, which behave similarly to the corresponding types in C, OpenCL provides fixed-length vector types such as float4 (4-vector of single-precision floats); such vector types are available in lengths two, three, four, eight and sixteen for various base types.[20]:§ 6.1.2Vectorized operations on these types are intended to map onto SIMD instructions sets, e.g., SSE or VMX, when running OpenCL programs on CPUs.[14] Other specialized types include 2-d and 3-d image types.[20]:10–11
The following is a matrix-vector multiplication algorithm 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;
}
The kernel function matvec computes, in each invocation, the dot product of a single row of a matrix A and a vector x:
To extend this into a full matrix-vector multiplication, the OpenCL runtime maps the kernel over the rows of the matrix. On the host side, the clEnqueueNDRangeKernel function does this; it takes as arguments the kernel to execute, its arguments, and a number of work-items, corresponding to the number of rows in the matrix A.
This example will load a fast Fourier transform (FFT) implementation and execute it. The implementation is shown below.[22] The code asks the OpenCL library for the first available graphics card, creates memory buffers for reading and writing (from the perspective of the graphics card), JIT-compiles the FFT-kernel and then finally asynchronously runs the kernel. The result from the transform is not read in this example.
#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);
}
The actual calculation inside file "fft1D_1024_kernel_src.cl" (based on Fitting FFT onto the G80 Architecture):[23]
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);
}
)"
A full, open source implementation of an OpenCL FFT can be found on Apple's website.[24]
In 2020 Khronos announced [25] the transition to the community driven C++ for OpenCL programming language[26] that provides features from C++17 in combination with the traditional OpenCL C features. This language allows to leverage a rich variety of language features from standard C++ while preserving backward compatibility to OpenCL C. This opens up a smooth transition path to C++ functionality for the OpenCL kernel code developers as they can continue using familiar programming flow and even tools as well as leverage existing extensions and libraries available for OpenCL C.
The language semantics is described in the documentation published in the releases of OpenCL-Docs[27] repository hosted by the Khronos Group but it is currently not ratified by the Khronos Group. The C++ for OpenCL language is not documented in a stand-alone document and it is based on the specification of C++ and OpenCL C. The open source Clang compiler has supported C++ for OpenCL since release 9.[28]
C++ for OpenCL has been originally developed as a Clang compiler extension and appeared in the release 9.[29] As it was tightly coupled with OpenCL C and did not contain any Clang specific functionality its documentation has been re-hosted to the OpenCL-Docs repository[27] from the Khronos Group along with the sources of other specifications and reference cards. The first official release of this document describing C++ for OpenCL version 1.0 has been published in December 2020.[30] C++ for OpenCL 1.0 contains features from C++17 and it is backward compatible with OpenCL C 2.0. A work in progress draft of its documentation can be found on the Khronos website.[31]
C++ for OpenCL supports most of the features (syntactically and semantically) from OpenCL C except for nested parallelism and blocks.[32] However, there are minor differences in some supported features mainly related to differences in semantics between C++ and C. For example, C++ is more strict with the implicit type conversions and it does not support the restrict type qualifier.[32] The following C++ features are not supported by C++ for OpenCL: virtual functions, dynamic_cast operator, non-placement new/delete operators, exceptions, pointer to member functions, references to functions, C++ standard libraries.[32] C++ for OpenCL extends the concept of separate memory regions (address spaces) from OpenCL C to C++ features - functional casts, templates, class members, references, lambda functions, operators. Most of C++ features are not available for the kernel functions e.g. overloading or templating, arbitrary class layout in parameter type.[32]
The following code snippet illustrates how kernels with complex number arithmetic can be implemented in C++ for OpenCL language with convenient use of C++ features.
// 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
C++ for OpenCL language can be used for the same applications or libraries and in the same way as OpenCL C language is used. Due to the rich variety of C++ language features, applications written in C++ for OpenCL can express complex functionality more conveniently than applications written in OpenCL C and in particular generic programming paradigm from C++ is very attractive to the library developers.
C++ for OpenCL sources can be compiled by OpenCL drivers that support cl_ext_cxx_for_opencl extension.[33]Arm has announced support for this extension in December 2020.[34] However, due to increasing complexity of the algorithms accelerated on OpenCL devices, it is expected that more applications will compile C++ for OpenCL kernels offline using stand alone compilers such as Clang[35] into executable binary format or portable binary format e.g. SPIR-V.[36] Such an executable can be loaded during the OpenCL applications execution using a dedicated OpenCL API.[37]
Binaries compiled from sources in C++ for OpenCL 1.0 can be executed on OpenCL 2.0 conformant devices. Depending on the language features used in such kernel sources it can also be executed on devices supporting earlier OpenCL versions or OpenCL 3.0.
Aside from OpenCL drivers kernels written in C++ for OpenCL can be compiled for execution on Vulkan devices using clspv[38] compiler and clvk[39] runtime layer just the same way as OpenCL C kernels.
C++ for OpenCL is an open language developed by the community of contributors listed in its documentation[31]. New contributions to the language semantic definition or open source tooling support are accepted from anyone interested as soon as they are aligned with the main design philosophy and they are reviewed and approved by the experienced contributors.[19]
OpenCL was initially developed by Apple Inc., which holds trademark rights, and refined into an initial proposal in collaboration with technical teams at AMD, IBM, Qualcomm, Intel, and Nvidia. Apple submitted this initial proposal to the Khronos Group. On June 16, 2008, the Khronos Compute Working Group was formed[40] with representatives from CPU, GPU, embedded-processor, and software companies. This group worked for five months to finish the technical details of the specification for OpenCL 1.0 by November 18, 2008.[41] This technical specification was reviewed by the Khronos members and approved for public release on December 8, 2008.[42]
OpenCL 1.0 released with Mac OS X Snow Leopard on August 28, 2009. According to an Apple press release:[43]
Snow Leopard further extends support for modern hardware with Open Computing Language (OpenCL), which lets any application tap into the vast gigaflops of GPU computing power previously available only to graphics applications. OpenCL is based on the C programming language and has been proposed as an open standard.
AMD decided to support OpenCL instead of the now deprecated Close to Metal in its Stream framework.[44][45]RapidMind announced their adoption of OpenCL underneath their development platform to support GPUs from multiple vendors with one interface.[46] On December 9, 2008, Nvidia announced its intention to add full support for the OpenCL 1.0 specification to its GPU Computing Toolkit.[47] On October 30, 2009, IBM released its first OpenCL implementation as a part of the XL compilers.[48]
Acceleration of calculations with factor to 1000 are possible with OpenCL in graphic cards against normal CPU. [49] Some important features of next Version of OpenCL are optional in 1.0 like double precision or half precision operations.[50]
OpenCL 1.1 was ratified by the Khronos Group on June 14, 2010[51] and adds significant functionality for enhanced parallel programming flexibility, functionality, and performance including:
On November 15, 2011, the Khronos Group announced the OpenCL 1.2 specification,[52] which added significant functionality over the previous versions in terms of performance and features for parallel programming. Most notable features include:
On November 18, 2013, the Khronos Group announced the ratification and public release of the finalized OpenCL 2.0 specification.[54] Updates and additions to OpenCL 2.0 include:
The ratification and release of the OpenCL 2.1 provisional specification was announced on March 3, 2015 at the Game Developer Conference in San Francisco. It was released on November 16, 2015.[55] It introduced the OpenCL C++ kernel language, based on a subset of C++14, while maintaining support for the preexisting OpenCL C kernel language. Vulkan and OpenCL 2.1 share SPIR-V as an intermediate representation allowing high-level language front-ends to share a common compilation target. Updates to the OpenCL API include:
AMD, ARM, Intel, HPC, and YetiWare have declared support for OpenCL 2.1.[56][57]
OpenCL 2.2 brings the OpenCL C++ kernel language into the core specification for significantly enhanced parallel programming productivity.[58][59][60] It was released on May 16, 2017.[61] Maintenance Update released in May 2018 with bugfixes.[62]
The OpenCL 3.0 specification was released on September 30, 2020 after being in preview since April 2020. OpenCL 1.2 functionality has become a mandatory baseline, while all OpenCL 2.x and OpenCL 3.0 features were made optional. The specification retains the OpenCL C language and deprecates the OpenCL C++ Kernel Language, replacing it with the C++ for OpenCL language[19] based on a Clang/LLVM compiler which implements a subset of C++17 and SPIR-V intermediate code.[63][64][65] Version 3.0.7 of C++ for OpenCL with some Khronos openCL extensions were presented at IWOCL 21. [66]
When releasing OpenCL 2.2, the Khronos Group announced that OpenCL would converge where possible with Vulkan to enable OpenCL software deployment flexibility over both APIs.[67][68] This has been now demonstrated by Adobe's Premiere Rush using the clspv[38] open source compiler to compile significant amounts of OpenCL C kernel code to run on a Vulkan runtime for deployment on Android.[69] OpenCL has a forward looking roadmap independent of Vulkan, with 'OpenCL Next' under development and targeting release in 2020. OpenCL Next may integrate extensions such as Vulkan / OpenCL Interop, Scratch-Pad Memory Management, Extended Subgroups, SPIR-V 1.4 ingestion and SPIR-V Extended debug info. OpenCL is also considering Vulkan-like loader and layers and a ‘Flexible Profile’ for deployment flexibility on multiple accelerator types.[70]
OpenCL consists of a set of headers and a shared object that is loaded at runtime. An installable client driver (ICD) must be installed on the platform for every class of vendor for which the runtime would need to support. That is, for example, in order to support Nvidia devices on a Linux platform, the Nvidia ICD would need to be installed such that the OpenCL runtime (the ICD loader) would be able to locate the ICD for the vendor and redirect the calls appropriately. The standard OpenCL header is used by the consumer application; calls to each function are then proxied by the OpenCL runtime to the appropriate driver using the ICD. Each vendor must implement each OpenCL call in their driver.[71]
The Apple,[72] Nvidia,[73]RapidMind[74] and Gallium3D[75] implementations of OpenCL are all based on the LLVM Compiler technology and use the Clang compiler as their frontend.
As of 2016, OpenCL runs on Graphics processing units, CPUs with SIMD instructions, FPGAs, Movidius Myriad 2, Adapteva epiphany and DSPs.
The Khronos Group maintains an extended list of OpenCL-conformant products.[4]
Synopsis of OpenCL conformant products[4] | ||||
---|---|---|---|---|
AMD SDKs (supports OpenCL CPU and accelerated processing unit Devices), (GPU: Terascale 1: OpenCL 1.1, Terascale 2: 1.2, GCN 1: 1.2+, GCN 2+: 2.0+) | X86 + SSE2 (or higher) compatible CPUs 64-bit & 32-bit,[157] Linux 2.6 PC, Windows Vista/7/8.x/10 PC | AMD Fusion E-350, E-240, C-50, C-30 with HD 6310/HD 6250 | AMD Radeon/Mobility HD 6800, HD 5x00 series GPU, iGPU HD 6310/HD 6250, HD 7xxx, HD 8xxx, R2xx, R3xx, RX 4xx, RX 5xx, Vega Series | AMD FirePro Vx800 series GPU and later, Radeon Pro |
Intel SDK for OpenCL Applications 2013[158] (supports Intel Core processors and Intel HD Graphics 4000/2500) 2017 R2 with OpenCL 2.1 (Gen7+), SDK 2019 removed OpenCL 2.1,[159] Actual SDK 2020 update 3 | Intel CPUs with SSE 4.1, SSE 4.2 or AVX support.[160][161]Microsoft Windows, Linux | Intel Core i7, i5, i3; 2nd Generation Intel Core i7/5/3, 3rd Generation Intel Core Processors with Intel HD Graphics 4000/2500 and newer | Intel Core 2 Solo, Duo Quad, Extreme and newer | Intel Xeon 7x00,5x00,3x00 (Core based) and newer |
IBM Servers with OpenCL Development Kit for Linux on Power running on Power VSX[162][163] | IBM Power 775 (PERCS), 750 | IBM BladeCenter PS70x Express | IBM BladeCenter JS2x, JS43 | IBM BladeCenter QS22 |
IBM OpenCL Common Runtime (OCR) | X86 + SSE2 (or higher) compatible CPUs 64-bit & 32-bit;[165] Linux 2.6 PC | AMD Fusion, Nvidia Ion and Intel Core i7, i5, i3; 2nd Generation Intel Core i7/5/3 | AMD Radeon, Nvidia GeForce and Intel Core 2 Solo, Duo, Quad, Extreme | ATI FirePro, Nvidia Quadro and Intel Xeon 7x00,5x00,3x00 (Core based) |
Nvidia OpenCL Driver and Tools,[166] Chips: Tesla, Fermi : OpenCL 1.1(Driver 340+), Kepler, Maxwell, Pascal, Volta, Turing: OpenCL 1.2 (Driver 370+), OpenCL 2.0 beta (378.66), OpenCL 3.0: Maxwell to Ampere (Driver 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 with Volta, Quadro RTX with Turing, Ampere |
All standard-conformant implementations can be queried using one of the clinfo tools (there are multiple tools with the same name and similar feature set).[167][168][169]
Products and their version of OpenCL support include:[170]
All hardware with OpenCL 1.2+ is possible, OpenCL 2.x only optional, Khronos Test Suite available since 2020-10 [171][172]
None yet: Khronos Test Suite ready, with Driver Update all Hardware with 2.0 and 2.1 support possible
A key feature of OpenCL is portability, via its abstracted memory and execution model, and the programmer is not able to directly use hardware-specific technologies such as inline Parallel Thread Execution (PTX) for Nvidia GPUs unless they are willing to give up direct portability on other platforms. It is possible to run any OpenCL kernel on any conformant implementation.
However, performance of the kernel is not necessarily portable across platforms. Existing implementations have been shown to be competitive when kernel code is properly tuned, though, and auto-tuning has been suggested as a solution to the performance portability problem,[176] yielding "acceptable levels of performance" in experimental linear algebra kernels.[177] Portability of an entire application containing multiple kernels with differing behaviors was also studied, and shows that portability only required limited tradeoffs.[178]
A study at Delft University from 2011 that compared CUDA programs and their straightforward translation into OpenCL C found CUDA to outperform OpenCL by at most 30% on the Nvidia implementation. The researchers noted that their comparison could be made fairer by applying manual optimizations to the OpenCL programs, in which case there was "no reason for OpenCL to obtain worse performance than CUDA". The performance differences could mostly be attributed to differences in the programming model (especially the memory model) and to NVIDIA's compiler optimizations for CUDA compared to those for OpenCL.[176]
Another study at D-Wave Systems Inc. found that "The OpenCL kernel’s performance is between about 13% and 63% slower, and the end-to-end time is between about 16% and 67% slower" than CUDA's performance.[179]
The fact that OpenCL allows workloads to be shared by CPU and GPU, executing the same programs, means that programmers can exploit both by dividing work among the devices.[180] This leads to the problem of deciding how to partition the work, because the relative speeds of operations differ among the devices. Machine learning has been suggested to solve this problem: Grewe and O'Boyle describe a system of support-vector machines trained on compile-time features of program that can decide the device partitioning problem statically, without actually running the programs to measure their performance.[181]
In a comparison of actual graphic cards of AMD RDNA 2 and Nvidia RTX Series there is an undecided result by OpenCL-Tests. Possible advantage of Nvidia Cuda or OptiX are not here tested.[182]
By: Wikipedia.org
Edited: 2021-06-18 18:15:04
Source: Wikipedia.org