主机发出一个命令,提交一个内核到OpenCL设备上执行,OpenCL运行时将会创建一个整数索引空间。索引空间是OpenCL支持的一个N维值的网格,称为NDRange,其中N为1,2或3。三个长度为N的数据确定了NDRange的以下特征:
- 每个维度索引空间(或全局大小)的范围;
-
一个偏移指数F表明每个维度的初始索引值(默认为0);
-
一个工作组(局部大小)每个维度大小。
内核、关联内核参数的参数值和定义索引空间的参数,这三个定义了一个内核实例。对应这个索引空间中的各个点将分别执行内核的一个实例。我们将执行内核的各个实例称为一个工作项(work-item),工作项将由它在索引空间中的坐标来标识,这个坐标就是工作组的全局ID,值从F到F加上该维度元素个数减1。每个工作项使用内核定义的同样的指令序列,尽管指令序列是相同的,但是由于代码中通过全局ID选择的数据不同,因此每个工作项的行为也不同。工作项提供了对索引空间细粒度的分解。
多个工作项组织为工作组(work-group),工作组中工作项的数量由内核入队时的参数决定。工作组横跨了整个全局索引空间,提供了对索引空间粗粒度的分解。同样,每个工作组被指定了一个唯一的ID,值从0开始,到该维度中工作组个数减1。对于分配到一个工作组内的每个工作项,除了有一个全局ID,也赋予了一个局部ID来表示它在所属工作组中的位置,这个局部ID的值从0开始,到工作组内该维度元素个数减1。通过结合工作组ID和工作组中的局部ID可以唯一地定义一个工作项。
例如,定义一个2维索引空间。索引空间的工作项大小为(A X,AY),每个工作组大小为(BX,BY),全局偏移ID(FX,FY)。对于此种情况,索引空间的工作项总个数为AXAY,每个工作组中工作项个数为BXBY,则工作组的大小(CX,CY)的值为:
CX=ceil(AX/BX)
CY=ceil(AY/BY)
工作项在工作组内的局部ID为(lx,ly),大小为(0,0)~(BX-1,BY-1)。工作组的ID为(Wx,Wy),大小为(0,0)~(CX-1,CY-1)。对于工作项全局ID(gx,gy)可以结合全局ID(lx,ly)和工作组ID(Wx,Wy)来计算:
gx=Wx*BX+lx+FX
gy=Wy*BY+ly+FY
下图提供了一个具体的例子,其中各个小方块分别是一个工作项。对于这个例子,每个维度中使用默认偏移是0。
图中阴影方块的全局ID为(gx,gy)=(6,5),工作组ID(Wx,Wy)=(1,1),工作项局部ID(lx,ly)=(2,1)。