本文转载自微信公众号《LoyenWang》,作者LoyenWang。转载本文请联系LoyenWang公众号。背景看他妈的官方文档!——鲁迅一图胜千言。——高尔基解释:对不起,我用了一个醒目的标题;我将尝试从程序员的角度来解释OpenCL,目标是易于理解。如果达不到这个效果,就当我没说这个;子曾说过:不懂中间件的系统软件工程师不是好码农;计算语言):从软件的角度来看,它是一个异构平台编程的框架;从规范的角度来看,它是异构并行计算的行业标准,由KhronosGroup维护;异构平台包括CPU、GPU、FPGA、DSP,以及近几年流行的各类AI加速器;OpenCL由两部分组成:1)用于编写在OpenCL设备上运行的内核的语言(基于C99);2)OpenCLAPI,关于Runtime的实现Intel等各个厂商发布的opencl_runtime_16.1.2_x64_rh_6.4.0.37.tgz,以人工智能场景为例来理解。如果在AI芯片上运行人脸识别应用,CPU擅长控制,AI处理器擅长计算。软件的流程可以拆分,通过CPU控制处理前后视频流的输入输出,通过AI处理器完成深度学习模型运算,完成识别。这是一个典型的异构处理场景。如果AI芯片的SDK支持OpenCL,那么可以基于OpenCL开发上层软件。话不多说,我们来看看OpenCL的架构。2.OpenCL架构OpenCL架构可以从四个角度进行开发:平台模型、内存模型、执行模型和编程模型。2.1PlatformModel平台模型:硬件拓扑结构的抽象描述。平台模型由连接到一个或多个OpenCL设备的主机组成;OpenCLDevice可分为一个或多个计算单元ComputeUnit(CU);CU可以进一步划分为一个或多个处理单元ProcessingUnit(PE),最终的计算由PE完成;OpenCL应用程序分为两部分:主机代码和设备内核代码,其中Host运行主机代码并将内核代码作为命令设备提交给OpenCL,内核代码由OpenCL设备运行;2.2ExecutionModel执行模型:Host如何利用OpenCLDevice的计算资源完成一个高效的计算过程。ContextOpenCL的ExecutionModel由两个不同的执行单元定义:1)运行在OpenCL设备上2)Host程序运行在Host上;其中,OpenCL使用Context来表示内核的执行环境:Context包含以下资源:Devices:一个或多个OpenCL设备;KernelObjects:OpenCLDevice执行函数和相关参数值,通常定义在cl文件中;ProgramObjects:实现内核的源代码和可执行程序,每个程序可以包含多个内核;MemoryObjects:Host和OpenCL设备可见的变量,在内核执行时被操作;NDrange内核是执行模型的核心。它被放置在设备上以供执行。在内核执行之前,需要创建一个索引空间NDRange(一维/二维/三维);内核实例的执行称为work-item,work-item组织成work-group,work-group组织成NDRange,最后NDRange映射到OpenCLDevice的计算单元;有两种方法可以找到工作项:通过工作项的全局索引;先找到工作组号的索引,再根据本地索引号确定;取一维为示例:上图中一共有4个work-group,每个work-group包含4个work-item,所以local_size的大小为4,local_id从0开始重新计数;global_size表示整体大小,即有16个work-item,global_id从0开始计数;以二维为例:二维的计算方法与一维类似,global_id和local_id的大小可以通过结合global和local的大小得到。细节不同。桌子;三维方式类似,省略2.3MemoryModelMemoryModel:Host和OpenCLDevice如何查看数据OpenCL的内存模型包括以下几种内存:Hostmemory:Host端的内存,只能被Host直接访问;GlobalMemory:设备内存,可以被Host和OpenCLDevice访问,允许Host的读写操作,也允许OpenCLDevice中的PE读写,由Host负责分配并释放内存中的Buffer;ConstantGlobalMemory:设备内存,允许Host进行读写操作,而device只能读取,用于传输常量数据;LocalMemory:单个CU中的本地内存,Host看不到这个区域,也不能操作它,这个区域允许内部PE读写,也可以在PE之间和用户之间共享,需要注意同步和并发问题;PrivateMemory:PE的私有内存,Host和PE之间是看不到的;2.4编程模型在编程模型中,需要编写两部分代码:一部分是Host端,一部分是OpenCLDevice端;在编程过程中,核心是维护一个Context,它代表了整个Kernel的执行环境;从cl源码创建并编译Program对象,运行时创建Kernel对象和内存对象,设置相关参数和输入后,Kernel可以被送入队列执行,也就是Launch的过程核心;最后,等待计算结束,得到计算结果;3.编程流程上图展示了OpenCL应用程序开发的基本流程;话不多说,上代码!;话不多说,给我看代码!4、示例代码测试环境:Ubuntu16.04,安装IntelCPUOpenCLSDK(opencl_runtime_16.1.2_x64_rh_6.4.0.37.tgz);简化流程,示例代码不做容错处理,只保留关键操作;整个代码的作用是完成向量的加法运算;4.1主机端程序#include
