并行运算框架OpenCL的一些基本概念

(一)openCL基本思想

一、opencl面对异构平台需要完成的几个步骤:
1、发现构成异构系统的组件
2、探查这些组件的特征,使软件能够适应不同硬件单元的特定特征
3、创建将在平台上运行的指令块(kernel)
4、建立并管理计算中涉及的内存对象
5、在系统中正确的组件上按照正确的顺序执行kernel
6、收集最终结果

二、kernel在openCL设置上执行的流程
     kernel函数,在主机上调用,在设备上执行
1、host提出一条指令,提交一条kernel在一个opencl设备上执行;
2、host发出指令同时,openCL系统创建一个整数索引空间,每个索引对应的点将分别执行kernel的一个实例,这个点是opencl的最新计算单元,称之为work_item(工作项);
3、每个工作项都有一个对应的ID并且执行相同的指令序列,但是由于数据不同,所以工作项的行为可能会不同;
4、N多工作集合到一起构成一个work_group(工作组),每个工作组也有一个对应的ID以及内部工作项的局部ID,故work_item可以由全局ID或者工作组ID+局部ID进行确定;
5、★给定工作组的工作项会在一个计算单元的处理单元上并行处理,但是opencl也只能保证一个工作组的工作项并发执行;不同kernel甚至一个kernel中的不同工作组都有可能会串行执行,虽然他们通常是并行执行的,但是算法设计时不能依赖这一点。
6、N个工作组构成一个NDRange组元,NDRange是一个N维的索引网格;

三、宿主机
  虽然openCL的应用是在计算设备上进行,但是主机(host)扮演者组织者的角色。host其作用包括定义kernel、为kernel指定上下文、定义NDRange和队列等;队列控制着kernel如何执行以及何时执行等细节。

四、上下文(context)
   定义了整个OpenCL环境,其包括OpenCL kernel、计算设备、程序对象、内存对象。上下文使用cl_context来表现。上下文由以下资源定义:
1、设备:host使用的openCL设备集合
2、内核:在openCL设备上运行的内核函数
3、程序对象:实现内核的程序源代码和可执行文件,在运行时由宿主机程序构建,其类似一个动态库,可以从中获取kernel使用的函数。因为openCL程序可能在cpu、gpu、fpga等不同环境下运行,故不可能使用统一的程序对象,只能在宿主机运行时静态定义、直接加载或者动态生成。
4、内存对象:内存中对openCL设备可见的一组对象。由于一个异构平台需要管理多个地址空间,设备可能有各种不同的内存体系结构,为了处理这种情况,openCL提出来内存对象的概念。内存对象在宿主机上明确定义并在宿主机和openCL设备之间移动。这样就可以支持不同的平台了。

五、命令队列(command_queue)
   宿主机host与计算设备device之间的交互是通过命令完成的,这些命令由host创建后提交给命令队列,这些命令会在队列中等待直到被某一openCL设备执行,命令队列在定义上下文后被关联到某一计算设备。其主要包括三种命令:
1、内核执行命令,在openCL设备上处理单元上执行内核;
2、内存命令,host与device之间、不同device之间传递数据,将内存对象映射到host地址空间或者从host地址空间中解映射;
3、同步命令,对命令执行顺序加以约束。例如deviceB的执行需要deviceA的执行结果,可限制deviceB等待直到deviceA执行完成。由host与命令队列之间是异步执行机制,host不必等待队列执行完成即可开始新的任务,但如果需要host等待某一队列完成也可以通过同步命令进行约束。

六、内存模型
    openCL中的你内存模型有:宿主机内存、全局内存、常量内存、局部内存、私有内存

七、编程模型
    任务并行数据并行两种编程模型
     1、数据并行编程模型
     2、任务并行编程模型
    需要注意,即使内核执行采用乱序命令队列模式,仍有可能会被串行执行,故若两个内核执行之间有依赖关系,则有可能会被锁死。

(二)openCL基本框架
    openCL基本框架包括三个部分:openCL平台API、openCL运行时的API、openCL编程语言。
1、平台API
    平台(platform)在openCL中是指宿主机(host)、openCL设备(device)以及openCL框架的组合。一个异构计算平台可以包含一个或者多个平台,例如不同厂家的CPU和GPU可能会分别定义各自的openCL框架。则程序员需要查询当前系统中可用的框架以及其各自的性能,并选取其中的某些框架及其子集构成所需的平台。这些工作通过平台API实现,为系统设计上下文
2、openCL运行时的API
    一个庞大的的函数集合,其主要作用是满足上下文的应用需求,完成宿主机程序的大部分具体工作
   运行时API的第一个任务是创建命令队列并关联到某一个计算设备;第二个任务是创建动态库所需的程序对象;第三个任务是管理数据共享和对内核运行施加约束。
3、openCL编程语言
    由ISO C99语言派生而来的openCL C语言,其主要针对内核应用而生。由于ISO C99某些特性是针对CPU而言,故openCL C中删除了ISO C99的某些特性:递归函数、函数指针、位域。同时其也不支持很多标准库,包括stdio.h和stdlib.h。
openCL C为了保证不同设备之间的移植性,删除了很多C的特性,同时也增加了很多扩展语言:
a.矢量类型和这些类型实例上的操作;
b.地址空间限定符,支持openCL对多地址空间进行控制;
c.一组丰富的内置函数,支持openCL中才常用需求
d.全部和局部内存中处理无符号整数和单精度标量变量的原子函数



openCL架构示意图
并行运算框架OpenCL的一些基本概念