Opencl四大模型

opencl四大模型

一、平台模型

描述了协同执行的单个处理器(宿主机)及其一个或者多个能执行Opencl代码的处理器(设备)。它定义了一个抽象的硬件模型,供编程人员用于编写能够在设备上执行Opencl C函数(kernel)。

Opencl使用一种InstallableClient Drive 模型,这样不同厂商的平台就能够在系统中共存,现在的Opencl drive模型不允许不同厂商的GPU同时运行。

Opencl平台需要包含一个主处理器和一个或者多个Opencl设备。

平台模型定义了host和device的角色,并且为device提供了一种抽象的硬件模型。

一个device可以被划分成一个或者多个计算单元,这些计算单元在之后能被划分为一个或者多个"处理单元"。

Opencl四大模型

host负责管理层所有的Opencl设备,宿主机发起计算任务,选择特定的Opencl设备并建立计算环境,在AMD和Nvida的Opencl平台中,一般都指的是X86 CPU。

device主要负责数据运算操作,宿主机将计算任务和数据发送给Opencl设备,从而在相应平台和设备上运行应用。

应用可以使Opencl运行API时选择对应提供商提供的对应平台。

编写OpenCL C代码时,设备架构会被抽象成平台模型。供应商只需要将抽象的架构映射到对应的物理硬件上即可。

平台模型定义了具有一组计算单元的设备,且每个计算单元的功能都是独立的,计算单元也可以划分为更多的处理单元。

举个例子,AMD Radeon R9 290X图形卡(device)包含44个向量处理器(计算单元)。每个计算单元都由4个16通道SIMD引擎,一共就有64个SIMD通道(处理单元)。Radeon R9 290X上每个SIMD通道都能处理一个标量指令。运行GPU设备能同时执行44x16x4=2816条指令。

二、执行模型

定义了在主机上如何配置Opencl环境以及如何在设备上执行kernel。这包括在主机端建立上下文,提供主机-设备之间的交互机制,定义一个并发模型供在设备上执行kernel所用。

1、执行模型概念

Opencl是一个主从处理模型,根本是宿主机如何利用Opencl设备上大量计算资源进行有效计算。所以Opencl执行模型的任务就是如何高效地调用这些计算资源。

  • 宿主机将每一个处理单元(PE)分配一个索引号,这个唯一的索引号成为全局ID(Global ID),全体PE被看做一个工作空间的work-item。
  • 我们可以将对应的工作空间定义为一维、二维、三维,因为我们可能处理数组、图形乃至三维图像。
  • 为了更好的处理不同的数据,我们可以将工作空间进行粗粒度的划分,如将一部分ID划分到一组,这个组称为work-group,每一个组内也可以分配ID,不过这个ID称为局部ID(Local ID)。全局ID和局部ID存在映射关系。
  • OpenCL规范中使用一个长度为N的整数数组来描述工作空间的大小(N<=3)。数组中的数值对应相应维度上工作点的个数。
  • 如果将我们常见的三维魔方想象成一个工作空间,那么一维即为红色的一行,即一维个数为3,二维为红色那个面,二维个数为9,三维即为整个工作空间,三维个数为27。
    Opencl四大模型

2、上下文

计算机工作主要在Opencl设备上进行,但是宿主机也扮演着重要的角色。宿主机主要通过上下文(Context)管理Opencl设备。上下文指的是所管理硬件和软件资源,比如:

  • 设备:Opencl程序调用的计算设备。
  • 内核:在计算设备上执行的并行程序。
  • 程序对象:内核程序的源代码(.cl)和可执行文件。
  • 内存对象:计算设备执行Opencl程序所需要的变量。

上下文由宿主机使用API进行创建、管理、销毁。

宿主机:就是主机,这个概念是相对于子机而言的,比如你安装有虚拟机的话,那么相对于虚拟机而言,你正在使用的计算机就是宿主机,虚拟机是安装在主机上的,必须在主机上才能运行,主机就是一个“宿主”。

3、命令队列

宿主机主要通过命令对相应设备进行进行控制。
根据计算量的带大小,计算设备并不能立刻执行完被分配的任务。每一个计算设备都会有一个命令队列,命令队列只能管理一个计算设备。通过命令队列,就实现了宿主机和计算设备的异步控制与执行。

队列中的命令主要有三种:

  • 启动命令:Opencl设备开始执行内核程序。
  • 内存命令:在宿主机与内存设备之间移动数据,或者在两者之间进行内训映射。
  • 同步命令:约束命令在计算设备上的执行。
  • 乱序执行:命令按照在命令队列中的顺序进行发射,但不保证计算设备是按照这个顺序进行执行的。
  • 有序命令:命令按照在命令队列的顺序进行发射和执行,上一条命令执行完后才能发射下一条命令。

宿主机程序可以为一个计算设备创建多个命令队列(一个计算设备可以有多个命令队列)。这些命令队列没有关联,这也就意味着一个计算设备可以执行多个种类的任务,例如李华在用洗衣机洗衣物的时候去做饭。

4、事件

任何操作被作为一个命令入队到一个命令队列中,即任何以clEnqueue字样开头的API调用--都会产生一个事件(event)。事件在Opencl中有两大作用:

  • 1、表示依赖。
  • 2、提供程序剖析机制。

除了产生事件对象之外,以clEnqueue字样开头的API调用也使用“等待列表”作为参数。Opencl生成一个API调用事件,并将其作为多次连续调用参数来表示依赖关系。

每次clEnqueue调用都将阻塞直到等待列表中的所有事件完成。

三、内存模型

定义被kernel所用的抽象内存层次,无需考虑实际的底层内存框架。

Opencl将设备中的存储器抽象成四层结构的存储模型:

  • 全局内存:工作空间中的所有节点都可以读写。(全局变量)
  • 全局变量:工作空间中的所有节点都可以读,但不可以写。(全局常量)
  • 本地内存:同一个工作组中的工作节点可以进行读写,对其他工作组不可见。不能通过宿主机进行初始化。(当前文件的全局变量)
  • 私有内存:只属于工作节点。(函数中的局部变量)
    Opencl四大模型
    在程序运行期间,需要宿主机和计算设备进行数据交换,存在两种方式:
    * 数据拷贝进行:将需要的数据拷贝到工作空间,计算完成后再拷贝出去(穿形参)。
    内存映射:将需要计算的地址穿进去(传指针)。

四、编程模型

定义了如何将并发模型映射到物理硬件上。

计算的时候可以按照两种类型模型来进行计算:数据并行和任务并行。

  • 数据并行: 将需要计算的数据进行等分,分配给不同的计算设备进行计算。如果需要进行两个很大矩阵的求和运算,那么就可以将矩阵数据分成几份,那么理论上计算事件缩短为原来的1/N。这适用于数据相关联不大的计算任务。
  • 任务并行:如果计算数据量不大,但每一步骤前后依赖,如你必须先将水烧开才能下面条,如果你需要不断的煮面条,那么就可以将这个过程分成阶段,用好几个锅同时进行。具体细节参考工厂的流水线工作模式。

既然有数据或者任务的并行,那么同步就成为一个绕不开的节点。并行是指在计算设备执行内核的过程中,对于其他节点是绝对独立的,互不影响。Opencl有三种方式进行同步:

  • 同一个work-group的节点间进行数据同步。
  • 同一个命令队列中的命令进行同步。
  • 同一个上下文的命令队列进行同步。

参考文献:
http://coderdock.com/2017/08/28/OpenCL/OpenCL-1-四大模型介绍/
opencl异构计算