dsp_notes

地平线SoC 中如何使用dsp

https://developer.d-robotics.cc/forumDetail/118364000835765794

参考地平线开发者论坛中的帖子,如何拿到了他们的开发包,找到对应的sample code,是比较容易移植和开发的。需要注意的是编译 dsp 程序需要 xtensa 的license。

dsp 和 soc 之间是server 和 client 的关系,dsp 程序作为服务端,arm 端作为客户端,两者通过rpc 方式进行通信。

性能瓶颈

dsp 的频率是比 arm cpu 慢的,所以只是标量运算的场景是不适合dsp 的;从内存地址直接读数据的方式也是适合dsp,要尽量少走ddr io

性能方面,一是要利用dsp SIMD 指令,其有更多的寄存器和向量运算器,只有充分利用向量指令才能最大程度发挥dsp 的性能;二是要利用DMA 进行数据 fetch,直接从ddr 上拿数据 dsp 也是没有优势的,arm cpu 有 cache,一般从ddr 获取数据都要比dsp 更快,但是从 DMA 上取数据要比从 ddr 上快的多,具体频率关系要看具体的硬件说明,我感觉要快个几倍。从DMA 取数据除了快之外,还可以用他的异步接口,通过ping-pong 形式的两块内存,一块用于计算,一块用于提前取数据。

算法例子

对 uint8_t类型的数据求和,如何避免溢出?

  1. 将uint8_t类型的数据直接读取到 uint8_t 类型的向量寄存器中,对每个向量中的结果分别求和放到 uint16_t中,然后再把每个uint16_t 加到最后的结果uint_32中
  2. 将uint8_t类型的数据读取到 uint32_t 类型的向量寄存器中,此时的对应关系是每块 uint32_t 内存表示的都是一个 uint8_t数据
  3. 同样是将uint8_t类型的数据读取到 uint32_t 类型的向量寄存器中,但此时的对应关系是每块 uint32_t 内存表示的都是四个 uint8_t数据,然后再利用逻辑平移操作,将四个uint8_t的数据提取出来

逻辑平移 vs 算数平移

逻辑平移是不带符号的平移,不考虑正负数;而算数平移是带符号的平移,正负属性在平移前后不变


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!