移动端异构运算技术 - GPU OpenCL 编程(基础篇)

2023-10-29

一、前言

随着移动端芯片性能的不断提升,在移动端上实时进行计算机图形学、深度学习模型推理等计算密集型任务不再是一个奢望。在移动端设备上,GPU 凭借其优秀的浮点运算性能,以及良好的 API 兼容性,成为移动端异构计算中非常重要的计算单元。现阶段,在 Android 设备市场,高通 Adreno 和华为 Mali 已经占据了手机 GPU 芯片的主要份额,二者均提供了强劲的 GPU 运算能力。OpenCL,作为 Android 的系统库,在两个芯片上均得到良好的支持。

目前,百度 APP 已经将 GPU 计算加速手段,应用在深度模型推理及一些计算密集型业务上,本文将介绍 OpenCL 基础概念与简单的 OpenCL 编程。
(注:Apple 对于 GPU 推荐的使用方式是 Metal,此处暂不做展开)

二、基础概念

2.1 异构计算

异构计算(Heterogeneous Computing),主要是指使用不同类型指令集和体系架构的计算单元组成系统的计算方式。常见的计算单元类别包括 CPU、GPU 等协处理器、DSP、ASIC、FPGA 等。

2.2 GPU

GPU(Graphics Processing Unit),图形处理器,又称显示核心、显卡、视觉处理器、显示芯片或绘图芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上执行绘图运算工作的微处理器。传统方式中提升 CPU 时钟频率和内核数量而提高计算能力的方式已经遇到了散热以及能耗的瓶颈。虽然 GPU 单个计算单元的工作频率较低,却具备更多的内核数及并行计算能力。相比于 CPU,GPU 的总体性能 - 芯片面积比,性能 - 功耗比都更高。

三、OpenCL

OpenCL(Open Computing Language)是一个由非盈利性技术组织 Khronos Group 掌管的异构平台编程框架,支持的异构平台涵盖 CPU、GPU、DSP、FPGA 以及其他类型的处理器与硬件加速器。OpenCL 主要包含两部分,一部分是一种基于 C99 标准用于编写内核的语言,另一部分是定义并控制平台的 API。

OpenCL 类似于另外两个开放的工业标准 OpenGL 和 OpenAL ,二者分别用于三维图形和计算机音频方面。OpenCL 主要扩展了 GPU 图形生成之外的计算能力。

3.1 OpenCL 编程模型

使用 OpenCL 编程需要了解 OpenCL 编程的三个核心模型,OpenCL 平台、执行和内存模型。

平台模型(Platform Model)

Platform 代表 OpenCL 视角上的系统中各计算资源之间的拓扑联系。对于 Android 设备,Host 即是 CPU。每个 GPU 计算设备(Compute Device)均包含了多个计算单元(Compute Unit),每个计算单元包含多个处理元素(Processing Element)。对于 GPU 而言,计算单元和处理元素就是 GPU 内的流式多处理器。

执行模型 (Execution Model)

通过 OpenCL 的 clEnqueueNDRangeKernel 命令,可以启动预编译好的 OpenCL 内核,OpenCL 架构上可以支持 N 维的数据并行处理。以二维图片为例,如果将图片的宽高作为 NDRange,在 OpenCL 的内核中可以把图片的每个像素放在一个处理元素上执行,借此可以达到并行化执行的目地。

从上面平台模型部分可以知道,为了提高执行效率,处理器通常会将处理元素分配到执行单元中。我们可以在 clEnqueueNDRangeKernel 中指定工作组大小。同一个工作组中的工作项可以共享本地内存,可以使用屏障(Barriers)去进行同步,也可以通过特定的工作组函数(比如 async_work_group_copy)来进行协作。

内存模型 (Memory Model)

下图中描述了 OpenCL 的内存结构:

  • 宿主内存(Host Memory):宿主 CPU 可直接访问的内存。

  • 全局 / 常量内存 (Global/Constant Memory):可以用于计算设备中的所有计算单元。

  • 本地内存(Local Memory):对计算单元中的所有处理元素可用。

  • 私有内存(Private Memory):用于单个处理元素。

3.2 OpenCL 编程

OpenCL 的编程实际应用中需要一些工程化的封装,本文仅以两个数组相加作为举例,并提供一个简单的示例代码作为参考 ARRAY_ADD_SAMPLE (https://github.com/xiebaiyuan/opencl_cook/blob/master/array_add/array_add.cpp)。

本文将用此作为示例,来阐述 OpenCL 的工作流程。

OpenCL 整体流程主要分为以下几个步骤:

初始化 OpenCL 相关环境,如 cl_device、cl_context、cl_command_queue 等

 cl_int status;
// init device
    runtime.device = init_device();
// create context
    runtime.context = clCreateContext(nullptr, 1, &runtime.device, nullptr, nullptr, &status);
// create queue
    runtime.queue = clCreateCommandQueue(runtime.context, runtime.device, 0, &status);

初始化程序要执行的 program、kernel

 cl_int status;
    // init program
    runtime.program = build_program(runtime.context, runtime.device, PROGRAM_FILE);
    // create kernel
    runtime.kernel = clCreateKernel(runtime.program, KERNEL_FUNC, &status);

准备输入输出,设置到 CLKernel

 // init datas 
    float input_data[ARRAY_SIZE];
    float bias_data[ARRAY_SIZE];
    float output_data[ARRAY_SIZE];
    for (int i = 0; i < ARRAY_SIZE; i++) {
        input_data[i] = 1.f * (float) i;
        bias_data[i] = 10000.f;
    }
    // create buffers
    runtime.input_buffer = clCreateBuffer(runtime.context, CL_MEM_READ_ONLY |
        CL_MEM_COPY_HOST_PTR, ARRAY_SIZE * sizeof(float), input_data, &status);
    runtime.bias_buffer = clCreateBuffer(runtime.context, CL_MEM_READ_ONLY |
        CL_MEM_COPY_HOST_PTR, ARRAY_SIZE * sizeof(float), bias_data, &status);
    runtime.output_buffer = clCreateBuffer(runtime.context, CL_MEM_READ_ONLY |
        CL_MEM_COPY_HOST_PTR, ARRAY_SIZE * sizeof(float), output_data, &status);
    // config cl args
    status = clSetKernelArg(runtime.kernel, 0, sizeof(cl_mem), &runtime.input_buffer);
    status |= clSetKernelArg(runtime.kernel, 1, sizeof(cl_mem), &runtime.bias_buffer);
    status |= clSetKernelArg(runtime.kernel, 2, sizeof(cl_mem), &runtime.output_buffer);

执行获取结果

 // clEnqueueNDRangeKernel
    status = clEnqueueNDRangeKernel(runtime.queue, runtime.kernel, 1, nullptr, &ARRAY_SIZE,
                                    nullptr, 0, nullptr, nullptr);
    // read from output
    status = clEnqueueReadBuffer(runtime.queue, runtime.output_buffer, CL_TRUE, 0,
                                 sizeof(output_data), output_data, 0, nullptr, nullptr);
    // do with output_data
    ...

四、总结

随着 CPU 瓶颈的到来,GPU 或者其他专用计算设备的编程将是未来的一个重要的技术方向。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

移动端异构运算技术 - GPU OpenCL 编程(基础篇) 的相关文章

  • 各种FIFO硬件设计(FIFO概念、异步、同步、非2次幂深度FIFO)

    文章目录 一 FIFO概述 二 FIFO分类 三 FIFO重要信号与参数 3 1 信号 3 2 参数 3 2 1 data depth的确定 四 FIFO存储原理 五 同步FIFO 5 1 空满信号判断 5 2 同步FIFO源码 5 3 测
  • Verilog的奇技淫巧[更新中]

    1 Verilog常用的数据选择语句vect a b 或vect a b 转载自 MDY常用的数据选择语句Verilog明德扬论坛 Powered by Discuz vect为变量名字 a为起始位置 加号或者减号代表着升序或者降序 b是进
  • 平头哥(T-Head )开源RISCV处理器OpenC906 RTL仿真

    在过去的几年里 阿里集团平头哥陆续推出了几款RISCV处理器 有些处理器已经在产业界得到了应用 比如在某志的D1处理器中 就嵌入了平头哥的玄铁C906内核为 芯 RISCV虽然是一个开放标准 并且网络上也不乏一些开源核的RTL实现 但是商用
  • DDR的VTT有源端接和无源端接(slua886a笔记)

    DDR的VTT有源端接和无源端接 slua886a笔记 背景 对于DDR的VTT端接 一直有说法是有源端接可降低功耗 之前一直没仔细理解其中原因 现在找了些相关的资料来介绍和对比有源和无源端接 理解有源端接的优点和降低功耗的原理 主要基于读
  • Vivido添加pynq-Z2开发板

    一 下载pynq z2开发板文件 下载地址 https www tulembedded com FPGA ProductsPYNQ Z2 html 二 将下载的文件解压到vivado安装的位置 如果boards目录下面没有boards fi
  • HDLBits — Verilog Practice(每日一题)

    HDLBits Verilog Practice 每日一题 一 Getting Started 1 Getting Started 一 Getting Started 1 Getting Started 问题描述 Build a circu
  • PLL时钟约束

    方法 1 自动创建基时钟和 PLL 输出时钟 例 derive pll clocks 这一方法使您能够自动地约束 PLL 的输入和输出时钟 ALTPLL megafunction 中指定的 所有 PLL 参数都用于约束 PLL 的输入和输出
  • J-Link仿真器与JTAG和SWD下载与接线

    目录 1 JTAG 1 1JTAG今天被用来主要的三大功能 1 2JTAG引脚 1 3可选引脚 2 SWD 2 1 SWD引脚 2 2 可选择引脚 2 3 JTag和SWD模式引脚定义 3 J Link仿真器 4 IAR与MDK配置两种下载
  • Verilog HDL——分频 计数

    分频 计数 module traffic Clk 50M Rst Clk30 Clk 1Hz input Clk 50M Rst output Clk30 Clk 1Hz 分频器 reg Clk 1Hz 分频器 50M分频 reg 31 0
  • Matlab 高斯信道下QPSK通带通信系统的简单仿真

    1 原理 2 仿真 3 总结反思 4 参考资料 1 原理 QPSK的具体内容请参考百度 QPSK的调制jie框图大致如下 QPSK信号可以采用正交调制的方式产生 如第一张图片的左半部分 I路信号与cos 信号相乘 Q 路信号与sin信号相乘
  • 手把手教你Modelsim仿真【2020.4版本】

    首先新建一个文件夹 test5 打开Modelsim 依次选择 File gt Change Directory 把目录选择到创建的 test5 文件夹 创建库 依次选择 File gt New gt Library 一般我们选择第三个 库
  • verilog中wire和reg类型的区别

    module counter parameter CNT MAX 25 d24 999 999 input wire sys clk input wire sys rst n output reg led out reg 24 0 cnt
  • 最详细的Vivado安装教程

    V i v a d o 安 装
  • 跨时钟域处理方法(一)——打拍

    一 说明 处理跨时钟域的数据可以分为单bit数据和多bit数据 而打拍的方法主要常见于处理单bit数据的跨时钟域问题 打拍的本质是通过添加寄存器 对输入的数据进行延拍 其主要目标是消除亚稳态的影响 常见的是打2拍 也就是添加2级寄存器 二
  • 【Xilinx DDR3 MIG】Xilinx FPGA DDR3读写实验相关用户接口引脚解释

    目录 DDR3读写实验 实验框图 时钟模块 DDR3读写及LED指示模块 MIG IP核 用户接口解释
  • 八段数码管动态显示(输入数据为BCD编码)

    八段数码管动态显示 输入数据为BCD编码 一 数码管概述 图1 八段共阴数码管内部等效原理图 图2 八段共阳数码管内部等效原理图 上面两图分别是对应八段共阴 共阳的数码管内部等效图 共阴是将八个LED数码管的阴极连接在一起接低 阳极segm
  • xilinx xdma PCIe中断bug

    xilinx xdma PCIe中断存在bug bug1 此中断虽然是msi或者msx中断 但是不中断cpu bug2 此中断不是边沿中断 而是电平中断 在驱动层需要不断地轮训查询中断事件 bug3 此中断持续时间必须长 而且在收到中断应答
  • 基于FPGA的AHT10传感器温湿度读取

    文章目录 一 系统框架 二 i2c接口 三 i2c控制模块 状态机设计 状态转移图 START INIT CHECK INIT IDLE TRIGGER WAIT READ 代码 四 数据处理模块 串口 代码 五 仿真 testbench设
  • [从零开始学习FPGA编程-24]:进阶篇 - 基本组合电路-编码器与译码器(Verilog语言)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 125247358 目录 前言 Veri
  • 无线网络管理系统与无线路由器的区别

    第5章 波形发生器软件设计 本章我们将介绍系统的软件设计 系统中控制软件占有很重要的地位 它不仅要产生波形数据 控制波形的发生 还要控制显示电路和键盘电路 因此系统软件的好坏直接决定着系统的功能和稳定 5 1软件的总体结构 在本系统中 由于

随机推荐

  • LVGL V8下png图片缩放显示

    这几天在研究LVGL V8下显示png图片和缩放问题 1 软件硬件环境 硬件环境 宸芯科技的SS202X系列芯片 这里使用的是SS202D 软件环境 Linux 移植的嵌入式系统 LVGL V8 编译器 arm linux gnueabih
  • 【c++模板笔记一】模板的介绍及其重载

    2015年2月11日 周三晴 有一段时间没有更新博客了 这几天在整理前段时间所学的c 知识点就没有更新了 最近开始研究c 的模板的STL 于是开始继续写下自己的一点所得吧 模板和STL都是c 中比较实用的东西 能把我们省下很多事情 简化编码
  • mybaits 代码自动生成

    https github com zhengjunbase codehelper generator GenDaoCode使用方法 主菜单Tools gt Codehelper gt GenDaoCode按键便可生成代码 方法一 点击Gen
  • 蓝桥杯模拟赛B组(大一报了直呼上当)

    这周蓝桥杯举行了模拟赛 需交费 交完后大家发现上当了 没想到这难度居然是小学生水平 这明显是在 咳嗽声 好 回归正题 今天博主给你们带来部分B组题题解 让你们重拾信心 继续进军省赛 目录 第一题 解析 实现 第二题 解析 第三题 解析 代码
  • Daily paper reading

    20180207 Nature Review Studying and modifying brain function with non invasive brain stimulation Brain derived neurotrop
  • ActiveMQ订阅模式持久化实现

    我的诉求是 建一个订阅通道 然后多个客户端监听 当某个客户端掉线后 再上线的时候可以收到它没有接收到的消息 本文主要参考了 使用Spring配置ActiveMQ的发布订阅模式 http nettm iteye com blog 182826
  • 【pytorch冻结网络参数:最全版】

    动机和意义 首先要搞清楚使用为什么要冻结某些层 以及那些层能够被冻结 冻结网络参数的一些动机 避免过拟合 当训练数据较少时 神经网络容易过拟合 即在训练集上表现很好 但在测试集上表现差 冻结一些参数可以减少网络的自由度 避免过拟合 加速训练
  • Java多线程 常见面试题

    1 什么是线程 线程是操作系统能够进行运算调度的最小单位 它被包含在进程之中 是进程中的实际运作单位 程序员可以通过它进行多处理器编程 你可以使用多线程对运算密集型任务提速 比如 如果一个线程完成一个任务要100毫秒 那么用十个线程完成该任
  • Unix系统 - 进程管理

    写在前面 注意 本章除了讲解进程管理 还包含网络编程Socket API的知识 这里写目录标题 一 进程 1 1基础知识 1 1 1进程ID 1 1 2查看进程 1 1 2 父子进程概念 1 1 3得到进程ID的函数 1 2 进程运行 1
  • SpringBoot教学资料6-SpringBoot登录注册功能实现(带简单前端)

    项目样式 SQL CREATE TABLE t user id int 11 NOT NULL AUTO INCREMENT username varchar 32 NOT NULL password varchar 32 NOT NULL
  • JavaScript 教程 (详细 全面)

    文章目录 JavaScript 是什么 JavaScript 简介 1 JavaScript 的历史 2 JavaScript 与 ECMAScript 的关系 3 如何运行 JavaScript 4 JavaScript 具有以下特点 N
  • 题目:根据当月利润,求应发放奖金总数

    题目描述 企业发放的奖金根据利润提成 利润低于或等于10万元时 奖金可提10 利润高于10万元 低于20万元时 低于10万元的部分按10 提成 高于10万元的部分 可提成7 5 20万到40万之间时 高于20万元的部分 可提成5 40万到6
  • 【Docker】Docker容器管理

    1 容器外部操作 1 通过实训平台进入到操作系统界面 在 后输入sudo docker run ubuntu 14 04 bin echo Hello world 命令 然后按Enter键 启动一个ubuntu容器 会输出 Hello Wo
  • 软件测试人员的职业发展路径和技术路线规划

    软件测试人员应该如何规划自己的职业发展路径 如何规划自己的技术路线 下面是我整理的两张图 大家可以参考这两张图 结合自已目前所处的技术水平阶段 自己的性格和特长 去提前定位个人的职业发展方向 规划下一步学习的内容 目录 一 技术路线图 准新
  • redis必杀命令:字符串(String)

    题记 Redis 字符串数据类型的相关命令用于管理 redis 字符串值 基本语法如下 redis 127 0 0 1 6379 gt COMMAND KEY NAME 字符串命令 序号 命令及描述 1 SET key value 设置指定
  • 贵金属白银行情走势图缘何强势?

    自从去年12月中以来 国际现货白银价格已经从底部抬升超过10 许多抓对行情节奏的投资者已经赚到了相当不俗的收益 但作为有专业素养的投资者 必须明白行情运行背后的逻辑 才能在日后的交易中再次占得先机 根据瑞士信贷2017全球财富报告 去年全球
  • VS code For win7 最后支持的一个版本是 1.70.3

    VS code For win7 最后支持的一个版本是 1 70 3 原本地址是 https update code visualstudio com 1 70 2 win32 x64 stable 实际地址 https az764295
  • 解决在Android studio的Button控件下background背景设置不起作用的问题

    Button控件默认的背景是深紫色的 想要修改背景色所以添加了background字段 但是又不起作用 其实是themes xml文件里的 style 标签 的 parent 属性设置不对
  • CentOS7设置IPv4&IPv6

    进入网卡目录 1 cd etc sysconfig network scripts 修改ONBOOT yes 2 vi ifcfg ens33 TYPE Ethernet PROXY METHOD none BROWSER ONLY no
  • 移动端异构运算技术 - GPU OpenCL 编程(基础篇)

    一 前言 随着移动端芯片性能的不断提升 在移动端上实时进行计算机图形学 深度学习模型推理等计算密集型任务不再是一个奢望 在移动端设备上 GPU 凭借其优秀的浮点运算性能 以及良好的 API 兼容性 成为移动端异构计算中非常重要的计算单元 现