opencl basics
1,适应平台
OpenCL是一个实现并行计算的编程框架,适应于CPU, GPU, DSP, FPGA
2,OpenCL架构
概念层:
- Platform model
- Execution model
- Memory model
- Programming model
编程层 - OpenCL Platform API
- OpenCL Runtime API
- OpenCL C(编程语言)
3,Platform Model
host <——> compute devices
host一般是CPU
Compute devices可以是CPU, GPU, DSP, FPGA
几层概念:
device —> compute unit —> processing element
每个物理核只有一个CU,每个CU有一个或多个PE
每一个OpenCL的实现都定义了一个“platform”,多个制造商的platform可以由一个host来控制
制造商会提供ICD:installable client driver model
编程时:
(1)包含头文件 CL/cl.h
(2)加载lib:libOpenCL.so
(3)ICD定义文件和平台专用的OpenCL库(devices制造商提供),一般位于/etc/OpenCL/vendors/
(4)运行时机制
- libOpenCL.so是动态链接的
- ICD 需要使用dlopen(..)来加载平台所需的OpenCL库
- 以上步骤完成后,调用OpenCL的库函数才能指向正确的实现
4,GPU上的线程管理
- Kernel的概念 --- 是在Device上执行的一个函数,多个kernel实例可以在并行线程上同时运行
- 线程数可多达上千个
线程管理的模型
- 上层:Grid (等同于NDRange)=> Device
- 中间层:Block (等同于work-group)=> Streaming Multi-Processor
- 底层:Thread (等同于work-item)=> Streaming Processor
总结:Grid包含Block包含Thread
调度器:
Block Scheduler — 将work-items分配到SM上,使用类似于round-robin方法实现负载均衡
Warp/Wavefront — Warp(Nvidia)将32个work-items同时调度和执行,而Wavefront(AMD)将64个work-items同时调度和执行
5,Execution Model
host — 执行host程序
device — 执行kernel
device上的层级:NDRange -> work-group -> work-item (grid -> block -> thread)
host定义Context
host管理Queues
6,Memory Model
首先,参与计算的所有memory包括:host端的memory,device端的memory;
其中device端的memory包括global and constant memory,以及work-group内的local memory,以及work-item内的private memory;
这几个memory的访问权限也不相同,
Host可以访问global和constant memory,不可以访问local和private memory;
kernel可以访问global,constant,local,private memory,对constant memory只读;
7,Programming Model
两种并行方案:
数据并行(适应GPU)
严格1:1映射,每个work-item对应一个data element
其他灵活的映射方案也是允许的
任务并行(适应多核CPU,多CPU)
单kernel实例的执行,并行方法:SIMD(通过OpenCL 向量数据类型),queue多任务异步执行
8,OpenCL Host端的基础编程步骤
(1)搞清楚异构计算系统的各个计算设备
(2)熟悉各个计算设备的属性
(3)编译和配置OpenCL kernels(编程语言OpenCL C)
(4)创建和初始化memory objects(例如buffers,images)
(5)在合适的计算设备上以正确的顺序执行kernels
(6)收集计算结果
9,OpenCL Host API
基本调用流程
- Query platforms
cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id * platforms, cl_uint *num_platforms) - Query devices of the platforms
cl_int clGetDeviceIDs(...) - Create context for the devices — 面向devices
cl_context clCreateContext(...) - Create queue ( for context and device ) — 面向context和某个device
cl_command_queue clCreateCommandQueue(...) - Create program object (for context) <— from C string
cl_program clCreateProgramWithSource(...)
Compile program
cl_int clBuildProgram(...)
Create kernel
cl_kernel clCreateKernel(...) - Create memory objects (within context)
cl_mem clCreateBuffer(…) - Kernel Execution
Set kernel arguments
cl_int clSetKernelArg(...)
Put kernel into queue
cl_int clEnqueueNDRangeKernel(...) - Copy memory objects with results from device to host
cl_int clEnqueueReadBuffer(...) - Clean up
cl_int clReleaseContext(clContext context)
cl_int clReleaseCommandQueue(cl_command_queue command_queue)
cl_int clReleaseProgram(cl_program program)
cl_int clReleaseKernel(cl_kernel kernel)
cl_int clReleaseMemObject(cl_mem memobj)
10,OpenCL for Compute Kernels
关于OpenCL C语言的一些介绍:
继承自从ISO C99
一些限制:没有递归,没有函数指针,没有C标准库函数
支持预处理(如#include)
内置数据类型:向量、指针、图像
必要的内置函数
可选的内置函数
函数限定符:__kernel 指定函数为kernel函数
地址空间修饰符:__global, __local, __constant, __private
Work-item函数:get_work_dim(), get_global_id(), get_local_id(), get_group_id()
在同一个work-group中的所有work-item必须同时执行barrier函数
同步函数:Barries — barrier(cl_mem_fence_flags flags)
memory fences — mem_fence(cl_mem_fence_flags flags)