在 ESP32-S3 上实现 SIMD 加速的计算机视觉:在 2 美元微控制器上实现高吞吐量
在 ESP32-S3 上实现 SIMD 加速的计算机视觉
针对 ESP32-S3 微控制器实现了一个 SIMD 加速的 FAST 特征检测器,利用其 128 位 SIMD 指令实现了约 220% 的吞吐量提升。这一优化使得低成本微控制器能够处理 30 帧每秒(fps)的 VGA 视频流,证明了在廉价边缘硬件上实现实时计算机视觉的可行性。
性能与硬件背景
ESP32-S3 在其价格点上是一款功能强大的微控制器,配备双核 CPU,运行频率高达 240MHz,并集成了 WiFi 和低功耗蓝牙无线电。FAST 特征检测器的实现利用了芯片有限但可用的 SIMD 指令,显著提升了处理速度。
在测试中,SIMD 加速的实现处理一帧 QVGA(320x240)图像大约需要 6 毫秒。整体吞吐量从 5.1 兆像素/秒(MP/s)提升到 11.2 MP/s,对于嵌入式系统来说,这是一个显著的性能提升。
技术挑战与解决方案
开发 SIMD 加速的 FAST 检测器需要直接使用 ESP32-S3 的汇编语言,并应对 Xtensa LX ISA 的若干特定硬件限制。
处理未对齐的内存访问
SIMD 架构不支持直接的非对齐读取。当围绕中心像素在基本方向(东和西)采样像素数据时,所需的内存块未对齐。通过使用一种特定的芯片指令解决了这个问题,该指令允许将两个连接寄存器中的一段提取到单个寄存器中,从而提取所需的像素数据。
克服有符号与无符号算术问题
ESP32-S3 的 SIMD 指令仅实现有符号八位数的比较,而像素数据存储为无符号八位数。直接将无符号数据重新解释为有符号数据会导致非线性映射问题,特别是在 128 到 255 的范围内,这会破坏标准比较操作。
为了解决这个问题,需要将像素值从无符号范围 [0, 255] 转移到有符号范围 [-128, 127]。由于 SIMD 算术运算是饱和的,标准减法不可行,这意味着高于 127 的值会钳位到 -128,而不是下溢。
通过利用二进制补码算术的性质克服了这一点。由于 $x - 128$ 等价于加上 $-128$,而 $-128$ 由最高位(0b10000000)表示,因此操作 $x - 128$ 可以通过将无符号字节 $x$ 与掩码 $0\text{x}80$ 进行异或来实现($x \text{ XOR } 0\text{x}80$)。这种技术允许处理器将无符号数据视为处于正确的线性范围内,以便进行比较和算术运算。
实现细节
实现涉及编写自定义汇编代码,包括一个名为 basm 的基本寄存器分配器,以管理底层操作。FAST 角点预测试通过设计一个函数来同时计算十六个像素的极值计数,与向量寄存器的容量相匹配,从而得到优化。
社区见解与进一步考虑
围绕该项目的技术讨论突出了关于 ESP32-S3 SIMD 功能和替代硬件的几点:
- SIMD 难度: 多位贡献者指出,ESP32-S3 上的 SIMD 指令复杂且难以有效使用。
- 性能指标: 一条评论澄清,报告的从 5.1 MP/s 到 11.2 MP/s 的提升是 120% 的增长,而不是 220% 的增长,因为百分比增长是相对于起始值计算的。
- 替代架构: 对于寻求更强大 SIMD 的用户,提到了 CH32V407/CH32V467 作为替代方案,它支持 RISC-V 向量扩展的嵌入式子集,提供了比 ESP32-S3 实现更宽的 SIMD ISA(64 位宽度)。