OpenCL没有定义主机代码如何工作的具体细节,只是定义了它通过命令队列与OpenCL设备如何交互。命令队列由主机或运行在设备中的内核(该功能需要支持OpenCL 2.0的设备!)提交给命令队列。命令会在命令队列中等待,直到被调度到OpenCL设备上执行。OpenCL的一个命令队列在上下文中关联到一个OpenCL设备。放入命令队列中的命令分为下列三种类型:
- 内核入队命令:将一个内核入队关联到同一个OpenCL设备的命令队列中;
-
存储器入队命令:将在主机与设备内存对象间传输数据,或者将内存对象映射到主机地址空间,或者从主机地址空间取消映射提交给命令队列;
-
同步命令:对命令队列中需要执行的命令施加执行顺序约束,如只有某个命令执行完成其他命令才能开始执行。
命令可以以异步方式执行,在这种方式下主机或运行在设备中的内核向命令队列提交命令,然后继续工作,而不必等待命令完成。如果有必要等待一个命令完成,可以利用命令执行相关的同步机制进行同步。
一个命令队列中的命令执行时可以有以下两种模式:
- 按序(in-order)执行:命令按其排入命令队列中的先后顺序执行,并按顺序完成。
-
乱序(out-of-order)执行:命令以任意顺序执行,通过显式的同步点或显式事件依赖项来约束顺序。
OpenCL平台都支持按序模式,但乱序模式是可选的。
需要注意的是,对于某些应用而言,算法在执行时,可能会有额外的计算,而这种额外的计算不能静态地确定。
与内核有关的计算,在运行时只作为内核实例执行。常规方法上,可以通过主机程序多次启动内核实例来执行,但这样会显著地增加开销或加重应用程序控制流。一个方便有效的方法就是从内核内部嵌套内核命令队列。对于支持OpenCL 2.0的设备,可以在设备上入队内核,不需要主机程序参与,这称为设备端队列,实现了嵌套并行。设备端内核命令队列与主机端内核命令队列类似,运行在设备上的内核(父内核)入队一个内核实例(子内核)到设备端命令队列。这个过程是乱序执行的。