关于RZ/G2L OpenCL应用运行方法介绍

描述

关于OpenCL

OpenCL是Open Computing Language的简写,目前已经形成了标准,是跨平台的,通常由图形处理器(GPU)提供硬件层面支持。OpenCL的设计目的,主要是为了将GPU强大的浮点和并行运算能力,以及能与CPU协作的能力,从软件层面开放给用户使用。用法跟OpenGL类似。

通常情况下,对同一组数据进行并行运算,使用OpenCL比执行普通CPU端程序,要快很多倍。

站在应用软件的角度,OpenCL简单来说,就是一组API函数名称,操作系统通常会提供具体实现库,以及运行于GPU之上的程序(OpenCL中称为kernel),文件后缀通常为.cl,基于OpenCL语法编写的程序,由CPU加载编译后,传输到OpenCL设备的内存供GPU执行。各个图形处理器厂商,针对自己的具体芯片,在GPU驱动程序中适配这些API,用户就可以基于这些标准的API进行相关的OpenCL应用程序开发。

需要指出的是:跟OpenGL的shader程序类似,OpenCL的kernel程序也是具体GPU芯片相关的,不能跨GPU型号使用。同一段代码,可能换了GPU型号之后就不能编译通过,第一个GPU使用的二进制kernel程序,不应该直接加载到第二个不同型号GPU上面使用。

OpenCL应用运行框图

视频编解码器

OpenCL设备内部,通常会有大量的并行计算单元(上图中的CU),每个计算单元内部又包含有若干个处理单元(图中的PE),PE可以同时并行地执行相同OpenCL代码,从而实现高性能并行运算,具体CU以及PE数量已经运算性能,跟具体GPU厂商的具体GPU型号有关。

OpenCL代码被CPU加载到设备内存之后,CPU通过相应的OpenCL API来启动OpenCL设备的运行,同时还能查询执行状态,实现CPU-GPU之间的同步,设备关闭等操作。

RZ/G2L上的OpenCL支持

RZ/G2L微处理器配备Cortex-A55(1.2 GHz)CPU、16 位 DDR3L/DDR4接口、带Arm Mali-G31的3D图形加速引擎以及视频编解码器(H.264),如下图红色框所示。此外,这款微处理器还配备有大量接口,如摄像头输入、显示输出、USB 2.0和千兆以太网,因此特别适用于入门级工业人机界面(HMI)和具有视频功能的嵌入式设备等应用。

此GPU支持2D/3D图形,以及通用GPU运算(GPGPU)。具体支持如下标准API:

● OpenCL 2.0 Full Profile

● OpenGL ES 1.1 2.0 3.0 3.1 and 3.2

视频编解码器

RZ/G2L上的OpenCL Library及其使用

RZ/G2L的VLP开发环境里面有提供Linux版OpenCL Library(需要从官网另外下载)以及对应头文件。

RZ/G2L的OpenCL库支持3种运行模式:

● CPU Mode:并行运算在CPU端完成,应用程序仍然需要调用OpenCL库API,OpenCL库内部会基于ARMv8 NEON SIMD指令集做针对性优化。

● GPU Mode:并行运行在GPU端完成,驱动程序会充分利用OpenCL设备的PE单元,提示并行性和运算效率。

● BOTH Mode:上面两种模式的结合。

通常情况下,BOTH Mode能提供最佳性能,典型做法是将待处理的并行数据,平均分成连续的两部分,CPU和GPU各自处理一半的数据(BOTH模式)。结合CPU模式,是因为CPU端有高主频,大Cache,高DDR带宽等优势。由于GPU端PE的特殊性,对待处理的数据,要求是,所有输入数据运算方法相同,没有依赖性,比如:两组输入数组A[1024]和B[1024]分别存放有1024字节的float类型数据,将A和B同序号的数据分别做乘法,结果保存于浮点数组C[1024],即:

C[0] = A[0] * B[0];

C[1] = A[1] * B[1];

… …

因为所有PE只能并行执行相同的kernel程序。

OpenCL库的使用,主要分为如下步骤:

● 获取平台信息

● 获取设备信息

● 创建上下文

● 创建命令队列

● 创建和编译kernel程序

● 创建kernel对象

● 创建内存对象

● 设置kernel参数

● 执行kernel程序

● 同步操作

● 获取处理结果

● 清理资源

部分OpenCL API介绍

OpenCL API通常以 cl_ 开头,很容易识别。

获取平台信息

cl_int clGetPlatformIDs(cl_uint num_entries,

     cl_platform_id *platforms,

     cl_uint *num_platforms);

这个函数是OpenCL应用程序必须调用的第一个API,用来获取可使用的Platform ID数组,当平台数未知时,第一次调用clGetPlatformIDs函数获取平台数量,第二次调用clGetPlatformIDs函数获取平台对象,供后续API使用。

cl_int clGetPlatformInfo(cl_platform_id platform,

     cl_platform_info param_name,

     size_t param_value_size,

     void *param_value,

     size_t *param_value_size_ret);

用于获取OpenCL的Profile信息、版本、平台制造商、支持的扩展等。

获取设备信息

cl_int clGetDeviceIDs(cl_platform_id_platform,

     cl_device_type device_type,

     cl_uint num_entries,

     cl_device_id *devices,

     cl_uint *num_devices);

这个API用来获取平台可使用的设备对象数组。可用于获取CPU/GPU/专用加速器等OpenCL设备数量等。

cl_int clGetDeviceInfo(cl_device_id device,

     cl_device_info param_name,

     size_t param_value_size,

     void *param_value,

     size_t *param_value_size_ret);

用于获取选定设备相关信息,如并行计算单元最大数量、设备端全局内存大小等信息。

由于OpenCL API涉及的内容比较多,另一方面,OpenCL相关标准已经很成熟,网上有很多的示例资源可供参考,瑞萨也可以提供MPU上的OpenCL例子给到客户,剩下的OpenCL应用程序步骤相关API,就不进一步介绍了。





审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分