本博文由 youngpan1101 出品,转载请注明出处。 文章链接:https://blog.csdn.net/youngpan1101/article/details/101866674 作者: 宋洋鹏(youngpan1101) 邮箱: yangpeng_song@163.com
ps:该笔记是基于《OpenCL异构并行计算:原理、机制与优化实践, 刘文志等著》的学习笔记
目录
OpenCL的基本介绍
OpenCL定义
OpenCL平台模型
OpenCL执行模型
上下文
命令队列
内核
存储器模型
存储器区域
存储器对象
共享虚拟存储器
OpenCL与CUDA
小结
本章将介绍OpecnCL平台模型、执行模型、存储器模型、OpenCL与OpenGL的关联。
OpenCL是一个为异构并行计算平台编写程序的工业标准,此异构计算平台可映射到CPU、GPU、DSP和FPGA等计算设备。使用OpenCL,开发人员可以编写在GPU上运行的通用计算程序,而无需将其算法映射到OpenGL或DirectX的3D图形API上。
为了描述OpenCL设计的核心,Khronos Group将OpenCL异构并行计算架构划分为:
平台模型(platform model)存储器模型(memory model)执行模型(execution model)编程模型(programming model)OpenCL平台模型由主机及其相连的一个或多个OpenCL设备组成,通常主机是指包含X86或ARM处理器的计算平台。每个OpenCL设备包含一个或多个计算单元(Compute Units),每个计算单元包含一个或多个处理单元(Processing Elements,设备上执行数据计算的最小单元)
OpenCL程序包含主机端程序和设备端内核(kernel)程序:
主机端程序运行在主机处理器上;内核在OpenCL设备上运行,内核通常是一些计算量大、逻辑比较简单的函数,OpenCL设备通过内核将输入数据计算处理后输出到主机,内核包括: OpenCL内核原生内核内建内核OpenCL设备没有IO处理能力,IO操作主要由主机完成,故OpenCL设备需要从主机上获得数据,在OpenCL设备计算完成后,又需要将数据从OpenCL设备复制回主机。
对于OpenCL执行模型来说,最重要的是上下文、命令队列和内核三个概念。
主机使用OpenCL API来创建和管理上下文,内核在此上下文中执行。
上下文定义了内核执行的环境,包含:
设备内核对象程序对象存储器对象上下文包括了一个或多个程序对象,此处的“程序” 可以把它想象成一个动态库,可以从中取出内核使用的函数。因为只有主机程序根据上下文中的设备特性,才能确定OpenCL应用最终是跑在CPU、GPU还是FPGA平台上,所以程序对象是在运行时由主机程序构建。OpenCL提供了两种方式从代码中构建对象,一种是从程序源代码中构建,另一种是从源代码中已经编译好的代码上构建。
为了适配不同平台的各自不同的存储器体系结构,OpenCL引入了存储器对象的概念。存储器对象在主机上会被明确定义,并在主机与OpenCL设备间交换数据。
命令队列由主机或运行在设备中的内核(该功能需要支持OpenCL 2.0的设备)提交给命令队列。命令会在队列中等待,直到被调度到OpenCL设备上执行。OpenCL的一个命令队列在上下文中关联到一个OpenCL设备。
放入命令队列中的命令可分为以下三种:
内核入队命令存储器入队命令同步命令一个命令队列中的命令执行时可以有以下两种模式:
按序执行(in-order)乱序执行(out-of-order)对于支持OpenCL 2.0的设备,可以在设备上入队内核,不需要主机程序参与,这称为设备端队列,实现了嵌套并行。
主机发出一个命令,提交一个内核到OpenCL设备上执行,OpenCL运行时将会创建一个整数索引空间,该空间时OpenCL支持的一个N维指的网格,称为NDRange,其中N为1,2或3。
索引空间中的各个点将分别执行内核的一个实例,将执行内核的各个实例称为一个工作项。多个工作项组织为工作组,工作组中工作项的数量由内核入队时的参数决定。对于分配到一个工作组内的每个工作项,除了有一个全局ID,也赋予了一个布局ID来表示它在所属工作组中的位置。
一个2维索引空间的工作项大小为(AX,AY) ,每个工作组大小为(BX,BY),全局偏移ID(FX,FY)。对于此种情况,索引空间的工作项总个数为 AX * AY,每个工作组中工作项个数为 BX * BY,则工作组的大小(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)为:
gx = Wx * BX + lx + FX; gy = Wy * BY + ly + FY;
从存储器区域、存储器对象、共享虚拟存储器三方面分析OpenCL存储器模型。
存储器区域包含主机与设备的内存,OpenCL中具体定义了如下几种不同的存储器区域:
主机内存(host memory):主机直接可用的内存;全局存储器(global memory):允许上下文中任何设备中所有工作组的所有工作项的读写;常量存储器(constant memory):全局存储器中的一块区域;局部存储器(local memory):对工作组是局部可见的;私有存储器(private memory):是一个工作项的私有区域。全局存储器和常量存储器可以在一个上下文内的一个或多个设备间共享,一个OpenCL设备关联局部存储器和私有存储器。
全局存储器中的数据内容通过存储器对象来表示,存储器对象分为三种不同类型:
缓冲(buffer)图像(image)管道(pipe)大多数情况下,主机和OpenCL设备存储器模型是独立的。而在某些情况下,他们是需要交互的。主机和设备间有三种交互方式:
读/写/填充映射和解映射拷贝在OpenCL 2.0中,OpenCL通过共享虚拟存储器(Shared Virtual Memory,SVM)机制扩展了全局存储器区域到主机内存区域的方式。OpenCL 2.0定义了三种SVM类型:
粗粒度SVM细粒度SVM细粒度系统SVMOpenCL和CUDA语法基本类似,对开发人员来说,若熟悉其一,也很容易熟悉另外一种编程语言,这也使CUDA和OpenCL程序之间的相互移植变得容易。