c++ - Neon/RPi 上的 64 位 DSP 滤波性能优化

标签 c++ embedded-linux

我在 ADI 公司的 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 函数一起工作,该函数实现了以基于块的方式处理数据所需的状态数组)。库 funcs 似乎适用于 64 位。但我怀疑它们是否适合 AArch64 并针对 AArch64 进行了优化,因为通常 CMSIS 标记为 32 位,类似的 Ne10。
    我正在探索自定义代码路径,我的问题是:
  • 什么样的 Neon 和 AArch64 特定优化是可能的
  • 与基于块的双二阶函数的普通 C 实现相比,可以预期的性能改进幅度

  • 或者当它留给编译器优化和使用 Neon 时就足够了?

    最佳答案

    如果您有选择,为了性能,您肯定希望选择 AArch64 而不是 32 位 Neon 实现。 AArch64 有更多/更宽的 vector 寄存器。并且 CPU 从乱序执行中获益更多,因为 AArch64 放弃了 32 位指令集无处不在的条件执行,这很容易通过条件标志导致指令之间的额外依赖。
    我个人最近从一个特定的优化任务中得出的结论:

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

  • 请注意,这些经验不应该泛泛而谈,这是一项特定的任务。
    通过手动优化实现获得多少性能取决于使用特定纯 C 代码的自动矢量化器的成功。
    我从一个普通的 C 实现开始,让它自动矢量化,研究了 llvm-mca 输出,发现了自动矢量化代码的弱点,并从那里开始工作。

    关于c++ - Neon/RPi 上的 64 位 DSP 滤波性能优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64115868/

    相关文章:

    c++ - 如何在C++中从文本文件中删除相似的值并将其分组?

    c++ - 错误 : AddressSanitizer: heap-buffer-overflow on address X at pc Y bp Z sp W

    perl - 如何在嵌入式系统上安装缺少的 perl 模块?

    linux - 在 Yocto ext4 Image 中设置 Linux 功能

    windows - Nano-X (Microwindow) 编程指南?

    linux - qvfb 编译错误 - 对 `png_create_write_struct' 的 undefined reference

    c++ - 调整模板提供的基类

    c++ - 为什么在语句中的其他任何地方都没有使用该值的情况下使用++i 而不是 i++ ?

    c++ - 使用 curl 下载到内存时出错

    c++ - 在 Qt 中使用 Wt