原文:知乎
文章发表于知乎专栏《移动端算法优化》
作者:高性能计算学院
一、Hexagon DSP
Hexagon 是高通公司数字信号处理器 (DSP) 产品系列的品牌名称。
Hexagon 也称为 QDSP6,代表“第六代数字信号处理器”。 第一代 QDSP6 V1 在 2006 年便已经推向市场,距现在已经过去十几年。据高通称,Hexagon 架构旨在为各种应用提供低功耗的性能,用于高通骁龙芯片,面向智能手机、汽车、可穿戴设备和其他移动设备,也用于蜂窝电话网络的组件。
A. 高通 SOC 架构图
高通骁龙 SOC 架构图
本篇中主要以 COMPUTE DSP 为核心展开讲述。
高通几款主流芯片的 DSP 参数
B. HVX 有哪些优势?
- 更强的数据并行处理能力,1024b 指令位宽,且有多个线程可并行,线程里面每个 packet 可同时并行执行四条指令。
- 更低的功耗。
- 更高的运行稳定性。
Single DSP/HVX 680 (725MHz) VS Quad Krait CPU (2.65GHz)
C. HVX 可以用来做什么?
HVX 以其优越的特性,能完美支持多个领域,比如虚拟现实、增强现实、图像处理、视频处理、计算视觉等等等。
二、DSP 硬件架构
如上图所示,我们所开发的主要涉及三个硬件资源:
- 主处理器(标量处理单元)
- HVX 协处理器(矢量处理单元)
- memory (VTCM 等)
A. HVX 架构 - 线程模型
- 主处理器主要负责标量运算,有 4 个(目前新架构已调整至 6 个)硬件线程(每个拥有 4 路 VLIW,共享 L1/L2)。
- 向量化运算由 2 个 HVX context 组成(目前新架构已调整至 4 个),分别会被多个标量线程控制。
- 主处理器和 HVX 都是可以有多个软件线程,由 QURT 实时操作系统进行硬件线程选择及调度,开发者不可控。
B. HVX 架构 - 内存
- Vector 单元可以直接访问 L2 cache
可以有效降低大块图像内存在 L1 上的平铺开销
提供单指令周期数据加载使用
可以支持全带宽
简化编程难度
- L1/L2 由硬件保持同步
- 提供 DDR 到 L2 cache 的流式预加载
- Vector 单元支持灵活的加载存储操作
非对齐方式读写
基于字节的条件状态判断
- (VTCM)向量化 TCM 支持
支持 vscatter/vgather 指令。
相对于 L2 cache,数据可以常驻,不存在数据刷出缓冲的问题。
支持 vmem 和 vmemu 指令直接访问。
C. HVX 架构 - SIMD 扩展
- 强大的 SIMD 扩展支持
支持 1024b SIMD * 4 Vector-slot VLIW
4096 result bits/cycle
- 支持 256 8x8 mpy,64 16x16 mpy
- 拥有 32 个 1024b 寄存器 R0-R31,4个判断寄存器 P0-P3 。
- 支持 8/16/32/64-bits 的定点运算。
- 提供特殊的 ISA
滑窗滤波指令
LUT 指令
直方图指令等
三、HVX软件架构
上图为 HVX 软件架构,主要分以下几个部分:
- User Application模块,host 端算法实现,主要作用是触发 FastRPC 调用,调度device 应用。
- FastRPC 模块,远程调用模块,实现 host 与 device 之间的通信,把 device 端算法 so 库从 host 端动态加载到 device 设备,host 调用 device 时会触发 FastRPC 调用,FastRPC 调用在 device 端会创建一个任务进程,完成 host 与 device 之间的调用过程。host 端会阻塞等待 device 端执行完成,属于阻塞等待。
- User Application (Hexagon SO) 模块,device 端算法实现,通过编译会生成一个 Hexagon so 文件。主要用于 device 端算法运行,同时还包含一系列辅助 API 接口等。
- libdspCV\_skel.so,这块主要是 dspcv 模块,在 Hexagon SDK 中的一个库文件,用来控制 device 端部分资源。例如时钟控制、多线程等功能封装。
- QuRT RTOS 模块,QuRT 的作用,主要负责系统资源维护,使用最多的主要是线程调用及 VTCM 等资源,根据线程的优先级将软件线程调度到硬件线程上,由这个 QuRT 操作系统来调度。
- CDSPPM & DCVS V2 模块,功率管理模块,主要提供时钟带宽的投票,用来管理时钟、power。
- Hardware thread,HVX context,最底层的硬件线程和HVX句柄。
A. 远程过程调用(RPC)
在介绍 HVX 动态加载过程之前先简单介绍远程调用的过程。远程调用,简单的理解就是一个节点请求另一个节点提供的服务。一个节点调用另一个节点的函数。
不在同一地址空间中,不能像本地调用一样直接调用函数,本地调用参数传递直接给到寄存器或者是压栈,传给被调用函数。但是远程调用不能这样直接调用。
远程调用时,首先客户端需要告诉服务器,需要调用函数,这里函数和进程 ID 存在一个映射,客户端远程调用的时候,需要查一下函数,找到对应的 ID,然后执行函数的代码。
客户端需要把本地参数传给远程函数,本地调用的过程中,直接压栈即可,但是在远程调用过程中不在同一个内存里,无法直接传递函数的参数,因此需要客户端将要调用的函数名以及参数打包,然后通过网络发送到服务器。
服务器解包数据,得到调用的函数以及参数,运行函数,并将结果打包,通过网络发送到客户端。
客户端解包数据,得到函数结果。
B. FastRPC
跟 RPC 的调用类似,通常算法会编译成两个库,一个在 host 端运行的 Stub 库,一个在 device 端运行的 Skel 库。两个库都会存放在设备的 host 文件系统中,在每个 host 端的线程中,host端第一次调用 device 端应用时, FastRPC 会将 device 端的 Skel 库动态加载到 device 端(这个操作会有额外耗时,所以初始化操作可异步进行)。然后,device 端的会根据 domain 信息进行应用匹配,并调用相应的算法,host 端会阻塞等待 FastRPC 调用结束。FastRPC 函数及结构体接口由 IDL 文件来映射(关于IDL 文件,将在后续内容进行讨论)。
host 端与 device 端数据零拷贝操作由高通基于 ION/DMA_BUF 实现,虚实转换由 SMMU 来进行映射完成,降低了开发者的使用难度。
FastRPC 用来作为两个处理器 host 和 device 的通信,每次触发 FastRPC 需要 0.5~2ms 的额外开销,尽量少触发 FastRPC 调用,函数调用尽量合并在 device 端去调用。
四、总结
通过前面的介绍我们了解到了高通 HVX 硬件架构、软件架构以及整个程序运行时的动态加载过程,这些都是常用异构调用的流程,需要仔细理清其中的调用逻辑及过程。
期望大家都能有所收获。
推荐阅读
更多嵌入式AI技术相关内容请关注嵌入式AI专栏。