OpenCL程序包含主机端程序和设备端内核(kernel)程序。主机端程序运行在主机处理器上,主机端程序以命令方式将内核程序从主机提交到OpenCL设备,OpenCL设备在处理单元上执行计算。根据这两个不同执行单元定义了OpenCL执行模型。
内核在OpenCL设备上执行,完成OpenCL应用的具体工作。内核通常是一些计算量大、逻辑比较简单的函数,OpenCL设备通过内核将输入数据计算处理后输出到主机。在OpenCL中定义了三类内核:
- OpenCL内核:用OpenCL C编程语言编写,并用OpenCL C编译器编译的函数。所有OpenCL实现都必须支持OpenCL内核和OpenCL C编程语言。
-
原生内核:OpenCL之外创建的函数,在OpenCL中可以通过一个函数指针来访问。例如,这些函数可以是主机源代码中定义的函数,或者是从一个专门库导出的函数。需要指出的是,执行原生内核是OpenCL的一个可选功能,原生内核的语义依赖于具体OpenCL实现。
-
内建内核:被绑定到特定设备,并不需要源码编译成程序对象的函数。常见用法是针对公开固定函数硬件或固件,将它们关联到一个特定的OpenCL设备或自定义设备。内建内核是OpenCL扩展功能,内建内核语义依赖于具体OpenCL实现。例如,Intel针对运动搜索,提供了block_motion_estimate_intel内建内核,使用clCreateProgram WithBuiltInKernels()函数来创建程序对象,block_motion_estimate_intel内建内核函数名“block_motion_estimate_intel”作为参数提供给clCreateProgramWithBuiltInKernels函数即可。
由于OpenCL设备通常没有IO处理能力,因此IO操作通常由主机承担,这意味着程序开始执行时,数据通常都在主机上,故OpenCL设备需要从主机上获得数据,在OpenCL设备计算完成后,又需要将数据从OpenCL设备复制回主机。
对于OpenCL执行模型来说,最重要的是上下文、命令队列和内核三个概念,理解了这三个概念就基本上理解了OpenCL的本质。