【OpenCL】初学摘要(一)

因项目需要,开始学习OpenCL了,这是基于我正在阅读的资料,整理出的一个摘要。方便以后自己回顾以及其他同学参考。没有列出所有函数的参数和返回值列表,可查询文档:

https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/

资料来源:OpenCL 2.0Reference Pages,AMD OpenCL大学课程ppt,OpenCL贴吧。

 

并行

任务并行:把一个问题分解为能够同时执行的多个任务。

数据并行:同一个任务内,它的各个部分同时执行。

多核GPU适合基于任务的并行编程,GPU更适应于数据并行编程。

在GPU上,一般通过循环展开(Loopstrip mining 技术),来把串行代码改成并行执行的。

GPU的程序一般称作Kernel程序,它是一种SPMD的编程模型。SPMD执行同一段代码的多个实例,每个实例对数据的不同部分进行操作。

在数据并行应用中,用loop stripmining来实现SPMD是最常用的方法:

  • 在分布式系统中,我们用MessagePassing Interface (MPI)来实现SPMD。
  • 在共享内存并行系统中,我们用POSIX线程来实现SPMD。
  • 在GPU中,我们就是用Kernel来显现SPMD。

在现代CPU上,创建回一个线程的开销很大,如果要在CPU上实现SPMD,每个线程处理的数据块就要尽量大点,做更多的事情,以便减少平均线程开销。但在GPU上,都是轻量级的线程,创建、调度线程的开销比较小,所以我们可以做到把循环完全展开,一个线程处理一个数据。

GPU上并行编程的硬件一般称作SIMD。通常,发射一条指令后,它要在多个ALU单元中执行(ALU的数量即使simd的宽度),这种设计减少了控制流单元以级ALU相关的其他硬件数量。

 

OpenCL架构

OpenCL可以实现混合设备的并行计算,这些设备包括CPU,GPU,以及其它处理器,比如Cell处理器,DSP等。使用OpenCL编程,可以实现可移植的并行加速代码。但由于各个OpenCL device不同的硬件性能,可能对于程序的优化还要考虑具体的硬件特性。

通常OpenCL架构包括四个部分:

  • 平台模型(PlatformModel)
  • 执行模型(ExecutionModel)
  • 内存模型(MemoryModel)
  • 编程模型(ProgrammingModel)

 

平台模型

不同厂商的OpenCL实施定义了不同的OpenCL平台,通过OpenCL平台主机能够和OpenCL设备之间进行交互操作。

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

OpenCL平台通常包括一个主机(Host)和多个OpenCL设备(device),每个OpenCL设备包括一个或多个CU(computeunits),每个CU包括又一个或多个PE(process element)。每个PE都有自己的程序计数器(PC)。主机就是OpenCL运行库宿主设备,在AMD和Nvida的OpenCL平台中,主机一般都指x86 CPU。

 

创建platform对象

clGetPlatformIDs函数通常要调用2次,第一次得到系统中可使用的平台数目,然后为平台(Platform)对象分配空间,第二次调用就是查询所有的平台,选择自己需要的OpenCL平台。


参数:

num_entries:可以加入platforms的cl_platform_id的表项数目。若platforms不是NULL,此项必须大于0。

platforms:会返回所找到的OpenCL平台的列表。platforms中cl_platform_id的值可以用于标识一个特定的OpenCL平台。如果platforms是NULL,则被忽略。所返回的OpenCL平台数目是num_entries和实际可用数目中较小的那个。

num_platforms:返回实际可用的OpenCL平台数目,若num_platforms是NULL,则被忽略。

返回值:

CL_SUCCESS,执行成功且有至少一个可用的平台。

CL_INVALID_VALUE,num_entries为0且platforms不是NULL,或者num_platforms和platforms都是NULL。

CL_OUT_OF_HOST_MEMORY,主机上OpenCL执行所需的资源分配失败。

CL_PLATFORM_NOT_FOUND_KHR,平台扩展cl_khr_icd为enabled且没有找到平台。

cl_khr_icd详见:

https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/cl_khr_icd.html

 

创建CPU设备

clGetDeviceIDs函数通常也是调用2次,第一次查询设备数量,第二次检索得到我们想要的设备。

【OpenCL】初学摘要(一)_第1张图片

参数:

platform,是clGetPlatformIDs所返回的平台ID或NULL。如果是NULL,其行为依赖于具体实现。

device_type,用来标识OpenCL设备类型的字段。这个设备类型可用来指定要查询特定的或所有可用的OpenCL设备。

num_entries,是cl_device_id表项的数目,此表项可添加进devices。若devices不是NULL,num_entries必须大于0。

devices,存放所找到的OpenCL设备的列表。Devices返回的cl_device_id的值可用来标识一个特定的OpenCL设备。若devices参数是NULL,则忽略此参数。所返回的OpenCL设备数目是num_entries和device_type类型的OpenCL设备数目中的较小值。

num_devices,与device_type相匹配的可用OpenCL设备的数目。若num_devices是NULL,则忽略此参数。

clGetDeviceIDs可能返回平台中所有与device_type匹配的实际物理设备,或其中的一个子集。

返回值:

CL_SUCCESS,执行成功。

CL_INVALID_PLATFORM,platform不是一个有效的平台。

CL_INVALID_DEVICE_TYPE,device_type不是一个合法值。

CL_INVALID_VALUE,num_entries等于0并且devices不是NULL,或者num_devices和devices都是NULL。

CL_DEVICE_NOT_FOUND,没有发现与device_type相匹配的OpenCL 设备

CL_OUT_OF_RESOURCES,设备上OpenCL执行所需的资源分配失败。

CL_OUT_OF_HOST_MEMORY,主机上OpenCL执行所需的资源分配失败。

 

创建context

通常,Context是指管理OpenCL对象和资源的上下文环境。为了管理OpenCL程序,下面的一些对象都要和Context关联起来:

  • 设备(Devices):执行Kernel程序对象。
  • 程序对象(Programobjects): kernel程序源代码
  • Kernels:运行在OpenCL设备上的函数
  • 内存对象(Memoryobjects): 设备上存放数据
  • 命令队列(Command queues): 设备的交互机制
  • 内存命令(Memorycommands)(用于在主机内存和设备内存之间拷贝数据)
  • kernel执行(Kernel execution)
  • 同步(Synchronization)

注意:创建一个Context的时候,我们必须把一个或多个设备和它关联起来。对于其它的OpenCL资源,它们创建时候,也要和Context关联起来,一般创建这些资源的OpenCL函数的输入参数中,都会有context。

clCreateContext函数指定了和context关联的一个或多个设备对象,properties参数指定了使用的平台,如果为NULL,厂商选择的缺省值被使用,这个函数也提供了一个回调机制给用户提供错误报告。

【OpenCL】初学摘要(一)_第2张图片

 

创建命令队列

在OpenCL中,命令队列就是主机的请求,在设备上执行的一种机制。

在Kernel执行前,我们一般要进行一些内存拷贝的工作,比如把主机内存中的数据传输到设备内存中。

注意:对于不同的设备,它们都有自己的独立的命令队列;命令队列中的命令(kernel函数)可能是同步的,也可能是异步的,它们的执行顺序可以是有序的,也可以是乱序的。

命令队列在device和context之间建立了一个连接。

命令队列properties指定以下内容:

  • 是否乱序执行
  • 是否启动profiling。Profiling通过事件机制来得到kernel执行时间等有用的信息,但它本身也会有一些开销。

如果创建成功,clCreateCommandQueueWithProperties返回一个非0的命令队列,并且errcode_ret置为 CL_SUCCESS。否则,返回NULL并将errcode_ret置为下列值中的一个:

CL_INVALID_CONTEXT,context无效。

CL_INVALID_DEVICE,device无效或未与context关联。

CL_INVALID_VALUE,properties的值无效。

CL_INVALID_QUEUE_PROPERTIES,properties的值有效但设备不支持。

CL_OUT_OF_RESOURCES,设备上的OpenCL实现在分配资源时失败。

CL_OUT_OF_HOST_MEMORY,宿主机上的OpenCL实现在分配资源时失败。

 


你可能感兴趣的:(OpenCL)