opencl中工作组,工作项

首先给出工作项,工作组的概念:

工作项:最简单的理解,一个循环中最里面的一次运算,称为一个工作项。

工作组:是由访问相同处理资源的工作项组成,其主要优势有:
a 工作组中的工作项可以访问高速内存(也叫局部内存)的同一块内存
b 工作组中的工作项可以通过栅栏(fence)和障碍(barrier)的方式来进行同步

处理单元:能够支持工作组的处理资源被称为处理单元。各个工作组都可以在单个处理单元上的执行,而各个处理单元一次只能够执行一个工作组。

有时,会需要在设备上对数据进行划分,形成工作组、工作项,个人的理解,之所以opencl中需要划分工作组,工作项,是因为:
a 工作项之间需要进行同步化处理,如果工作项之间需要进行同步化处理,那么,就需要对这些工作项进行工作组划分。因为只有工作项属于同一个工作组,才能够实现工作项同步化。所谓工作项的同步化,是由于,多个工作项之间可能会访问局部内存中的同一段数据,他们之间的执行顺序就可能得到不同的结果,甚至是错误。为了防止这种错误的产生,就需要在不同的工作项之间进行同步,工作项之间的同步有两种方法:第一种是栅栏(fence)和障碍(barrier),第二种是原子操作。
那么一个内核可以生成多少个相对应的工作项?工作项和工作组的数量是没有限制的。但如果一个设备只含有M个计算单元,每个工作组有N个工作项,那么任何时候,最多只能有MN个工作项来执行内核(如上面已经提到,一个计算单元一次只能够执行一个工作组)。
在单个设备上能够进行数据划分的函数只有一个:clEnqueueNDRangeKernel,这个函数的声明以及重要参数说明如下:

clEnqueueNDRangeKernel(cl_command_queue queue,cl_kernel kernel,cl_uint work_dims,const size_t *global_work_offset,const size_t *global_work_size,const size_t *local_work_size,cl_uint num_events,const cl_event *wait_list,cl_event *event)

work_dims:数据的维度数,其限定范围一般是1-3
global_work_offset:各个维度上 全局ID偏移量,说白了,就是各个维度上数据的起始点,比如二维数据,你希望的起始点是(1,3),就可以通过这个参数设置,一般我们的起始点是从(0,0)开始的
global_work_size:各个维度上的工作项的数量,注意,这里说的各个维度上的工作项的数量,指的是总体的,因为在下面还有一个参数会指定在一个工作组上各个维度上的工作项的数量,这个参数是:
local_work_size:各个维度上一个工作组中工作项的数量

    1
    2
    3
    4
    5
    6

创建工作组并不是必须的,如果参数local_work_size的取值被设置成NULL,opencl将分析决定如何在设备上的处理单元间分配工作项。
举例:
对于一个12x12的矩阵,将其划分为9个工作组,每个工作组是一个4x4的矩阵,有16个工作项,相应的设置:

cl_uint work_dims =2; //2维数据
size_t global_work_offset[2] = {0,0}; //从0,0开始
size_t global_work_size[2] = {12,12};
size_t local_work_size[2] = {4,4};
clEnqueueNDRangeKernel(command_q,kernel,work_dim,global_work_offset,global_work_size,local_work_size,0,NULL,NULL);

而对于另一个运算,比如,将一个8x8的图像与一个3x3的核进行卷积,放到一个6x6的图像中,如果不分组,可以直接将二维图像进行一维访问也可以:


size_t global_work_size[2] = {36};/6x6
size_t local_work_size[2] = {1};
clEnqueueNDRangeKernel(command_q,kernel,1,NULL,global_work_size,local_work_size,0,NULL,NULL);
---------------------


原文:https://blog.csdn.net/liyuan123zhouhui/article/details/52850282
 

猜你喜欢

转载自blog.csdn.net/boyemachao/article/details/88795102
今日推荐