虽然 OpenCL 应用的计算工作都在 OpenCL 设备上进行,但是主机也扮演着非常重要的角色。平台中一般存在着多个 OpenCL 设备,主机通过上下文来管理这些设备,并管理整个平台的运行。上下文中管理的硬件和软件资源如下:

  • OpenCL 设备: OpenCL 应用需要调用的计算设备。
  • 内核:在计算设备上执行的并行程序。
  • 程序对象:内核程序的源代码(Intel FPGA 不支持)和可执行文件。
  • 内存对象:计算设备执行 OpenCL 程序所需的变量。

 

对于上下文中关联的所有计算设备必须全都来自于同一平台,对于来自不同平台的OpenCL设备,需要为各个平台独立地建立上下文。对于同一平台的设备,上下文中可以关联多个设备。主机应用也可以使用多个上下文来管理多个设备。

 

 

 主机使用 OpenCL API 函数来创建和管理上下文,并利用上下文建立一个或多个命令队列(command queue)来协调某个 OpenCL 设备上内核的执行。主机通过 API 将各个将要在 OpenCL 设备上执行的命令放入命令队列中等待调度。与上下文可以管理多个OpenCL 设备不一样,命令队列只能管理所关联的唯一一个设备。队列中的命令可以是以下三种:

  • 内核执行命令:在 OpenCL 设备上执行内核。
  • 内存命令:读写内存对象,在主机地址空间和内存对象之间进行映射或解映射。
  • 同步命令:对命令的执行顺序加以约束。

由于这些命令是在主机上进行调度而在 OpenCL 设备上执行,因此命令的执行完全是异步的, OpenCL 为命令队列中的每个异步程序提供了两种执行模式:

  • 顺序执行:按照命令放入队列的顺序依次执行,只有前面的命令全部结束后才会启动后面的命令。
  • 乱序执行:按顺序发起命令,但后续命令不必等待前面的命令运行完毕即可执行, 在此模式下用户必须通过同步命令来管理各个命令之间的执行顺序。(Intel FPGA 不支持)

用户可以为命令队列上执行的每个命令指定一个事件(event)对象以用来控制和协调该命令的执行。

可以将多个命令队列关联到同一个上下文中,这些命令队列之间是相互独立的,没有明确的同步机制,适用于同时进行多个独立的任务。

在OpenCL上下文中,有内存、程序和内核对象,对这些对象的操作就需要使用命令队列。一条命令就是主机发送给设备的一条消息,用来高速设备执行一个操作。这个操作包含主机与设计间、设备内的数据拷贝与内核执行。命令提交到命令队列中,命令队列需要执行的命令发送给设备。需要注意的是,每条命令队列只能关联一个设备,如果要同时使用多个设备,则需要创建多个命令队列。


 

 下一讲我们介绍OpenCL 的内存模型。