【问题标题】:64-bit DSP filtering performance optimization on Neon/RPiNeon/RPi 上的 64 位 DSP 滤波性能优化
【发布时间】:2021-01-14 20:15:35
【问题描述】:

我在 Analog Devices Sharc DSP 处理器上有一个 32 位 C++ DSP 音频处理项目,需要将其转移到 64 位处理,该处理现在已经有一段时间可用于 ARM AArch64 的嵌入式用例。

我正在考虑两种选择:

  • 要么使用我自己的 FIR 和 IIR 过滤自定义实现,要么
  • 寻找一些针对 AArch64 和 Neon 优化的库函数。

在 64 位精度之上,我有相当多的 CPU 密集型处理。我还需要获得更多的处理能力,因为目前 Sharc 的性能也是一个瓶颈。 IIR 和 FIR 函数应提供 64 位实时、基于块的信号处理。

我的目标平台是 Raspberry Pi,3B+ 可能是 4。提供了我需要的功能,例如在 CMSIS 库中为 arm_biquad_cascade_df2T_f64()(它实际上与一个补充的 init 函数一起工作,该函数实现了以基于块的方式处理数据所需的状态数组)。库函数似乎适用于 64 位。但我怀疑它们是否适合 AArch64 并针对 AArch64 进行了优化,因为通常 CMSIS 标记为 32 位,Ne10 类似。

我正在探索自定义代码路径,我的问题是:

  • 可以进行何种 Neon 和 AArch64 特定优化
  • 与基于块的双二阶函数的纯 C 实现相比,可以预期的性能提升幅度

或者,留给编译器优化和使用 Neon 就足够了?

【问题讨论】:

  • 你知道godbolt.org 吗?使用它来查看您的 C 实现将如何被优化。将编译器设置为最接近实际使用的 GCC,传递正确的标志。
  • 你能编辑你在“Raspberry Pi”段落中的第二句话吗?很难跟上。
  • 句子已编辑,谢谢

标签: c++ embedded-linux


【解决方案1】:

如果您可以选择,出于性能考虑,您肯定会选择 AArch64 而不是 32 位 Neon 实现。 AArch64 有更多/更宽的向量寄存器。而且 CPU 从乱序执行中获益更多,因为 AArch64 丢弃了无处不在的 32 位指令集的条件执行,这很容易通过条件标志导致指令之间的额外依赖。

我最近从一项具体的优化任务中得出的个人结论:

  • clang 管理比 gcc 更好的自动向量化
  • clang 10 比 clang 8 有更好的自动向量化
  • clang 针对特定 Cortex 内核的调优令人印象深刻
  • 有用的clang标志:-Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize
  • 没有一个编译器能够克服 AArch64 向量聚集加载的不足
  • 手动矢量化代码的性能仍然比自动矢量化高 2 倍
  • 使用 ARM 向量内在函数进行编程受到索引文档不佳以及 ARM 将所有向量指令从 ARMv7 重命名为 AArch64 的阻碍
  • 使用 llvm-mca (https://llvm.org/docs/CommandGuide/llvm-mca.html),非常有用

请注意,这些经验不应随意概括,这是一项特定的任务。

通过手动优化实现获得多少性能取决于自动矢量化器使用特定纯 C 代码是否成功。

我从一个普通的 C 实现开始,让它自动矢量化,研究 llvm-mca 输出,发现自动矢量化代码的弱点,然后从那里开始工作。

【讨论】:

  • 要在这里打破规则并说这是一个非常好的答案!感谢您发布它!
猜你喜欢
  • 2015-01-08
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 2021-01-20
  • 2012-04-06
相关资源
最近更新 更多