基础概览
原理建议阅读下面文章,文中介绍了OpenCL相关名词概念: http://opencl.codeplex.com/wikipage?title=OpenCL%20Tutorials%20-%201 (英文版)
用GPU计算两个数组之和
OpenCL支持德平台、设备很多,为了兼顾不同设备,OpenCL程序的第一步就是确定OpenCL执行的平台,在确定平台之后再确定执行OpenCL计算的设备。确定设备后创建上下文,上下文中包含上一步查询的OpenCL计算的设备(允许包含多个计算设备对象),以及接下来创建的内核、程序对象和内存对象。创建上下文以后,需要创建命令队列,但一个OpenCL设备可以对应多个队列。例如,如果需要使用上下文中包含的两个计算设备时,为每个设备创建各自的命令队列。主机与OpenCL设备间数据传输、执行内核等交互操作都是通过入队到命令队列中,命令队列中的各个命令交给OpenCL驱动或相应的硬件单元去执行。由于在运行时才知道OpenCL设备信息,所以在OpenCL主机端程序中读取内核源码并创建程序对象,根基OpenCL设备编译、构建程序对象,最后创建内核对象。通过这三步操作,把OpenCL设备上执行的内核代码编译完成。对于在OpenCL设备上执行的内核函数需要输入参数,在主机端调用设置内核参数函数。除此之外,还需要设置在设备上用于执行的工作组和工作项的参数。当上述操作都完成以后,我们就可以把内核函数入队到命令队列中,命令队列提交给相应的设备执行。OpenCL设备执行完计算后,把数据拷贝回主机端,并销毁分配的资源。
device.cl代码:
执行结果:
对于上下文中关联的所有计算设备必须全都来自于同一平台,对于来自不同平台的OpenCL设备,需要为各个平台独立地创建上下文。对于同一平台的设备,上下文中可以关联多个设备。主机应用也可以使用多个上下文来管理多个设备,甚至同一平台多个设备都可以关联到不同的上下文。
命令提交到命令队列中,命令队列把需要执行的命令发送给设备。需要注意的是,每条命令队列只能关联一个设备,如果要同时使用多个设备,则需要创建多个命令队列,每个命令队列关联到一个设备。命令队列中的命令,只能是主机发送给设备,而设备不能发送命令给主机。
程序对象与内核对象是OpenCL中两个最重要的对象,这两个对象关系到设备上执行的代码,以及代码执行所实现的功能。对于内核对象而言,一个内核对象代表的就是一个在设备上执行的函数;而对于程序对象而言,一个程序对象就是内核的一个容器。打个比方:程序对象就好比一个集群系统,内核对象就好比在这个集群系统,内核对象就好比在这个集群系统中的节点,多个节点组成了这个集群系统,同时对于每个节点而言可以执行不同的任务(程序对象里的每个内核函数实现功能不同)。换句话说,我们通常会在一个.cl文件里写上多个内核函数,甚至写上多个.cl文件,包含多个内核函数。一个程序对象包含了对所有指定cl源文件编译、构建后的一个二进制目标对象。而一个内核对象则表示其中某一个内核执行函数。