目地
- OpenCL:跨平台的通用计算框架,将异构平台抽象化为主机部分和设备部分,主机与设备通过命令队列传递指令。适配于多家公司推出的计算平台,包括但不限于AMD、Intel、NVIDIA和Apple。
- CUDA:由NVIDIA推出的通用并行计算架构,仅用于NVIDIA系列的计算设备。
计算流程
- OpenCL:OpenCL将除主机外的所有抽象化元素规范在一个上下文中,在之后进行的计算中,只需要维护这一个上下文即可。执行流程可以抽象化为:查询平台->查询设备->创建上下文->创建命令队列->创建内存对象->创建程序对象->编译程序对象->创建内核对象->设备内核参数->执行内核。
- CUDA:一般情况下,CUDA程序的流程如下:
头文件包含
常量定义
自定义函数和CUDA核函数的声明(原型)
int main(void)
{
分配主机与设备内存
初始化主机中的数据
将某些数据从主机复制到设备
调用核函数在设备中进行计算
将某些数据从设备复制到主机
释放主机与设备内存
}
自定义函数和CUDA核函数的定义
线程组织
- OpenCL:OpenCL运行时会创建一个整数索引空间,这个索引空间最多是3维的,称为NDRange。NDRange中每一个点称为一个工作项,也就是一个线程。每一个工作项执行内核的一个实例,工作项由它在的索引空间的坐标来标识,这个坐标就是工作组的全局ID。多个工作项组织为工作组,工作组由参数决定数量。看图更清楚:

图中(Gx,GyG_x, G_yGx,Gy)是索引空间的大小,大的划分区域是工作组,大小是(Sx,SyS_x, S_ySx,Sy)。如图假定工作组的在全局索引中的坐标是(wx,wyw_x, w_ywx,wy),那么其中的每一个工作可以表示为(wx∗Sx+lx,wy∗Sy+lyw_x*S_x+l_x, w_y*S_y+l_ywx∗Sx+lx,wy∗Sy+ly),其中(lx,lyl_x, l_ylx,ly)是工作项在工作组中的ID。工作项的ID也可以使用全局索引,使用内置函数即可,具体查看OpenCL文档。 - CUDA:CUDA中的线程组织与OpenCL类似,其拥有Grid和Block两个概念。从开普勒架构开始,线程块(block)的最大线程数是1024个,网格(grid)的大小最大是231−12^{31}-1231−1。现在假定程序已经指导你设置的线程情况,每个线程都有独特的ID,这些ID可以由CUDA核函数中的内建变量计算获得。
这些内建变量可以是:(x维度是变化最快的)
gridDim.x gridDim.y gridDim.z分别是grid 的 x维度、y维度和z维度
blockDim与gridDim类似
blockIdx.x 取值范围是0到gridDim.x-1
threadIdx.x 取值范围是0到blockDim.x-1