我在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就足够了吗?

    最佳答案

    如果您有选择,那么为了性能,您肯定会选择AArch64而非32位Neon实现。 AArch64具有更多/更广泛的 vector 寄存器。由于AArch64放弃了普遍存在的32位指令集的条件执行,CPU可以从乱序执行中获得更多 yield ,这很容易通过条件标志引起指令之间的额外依赖。
    我最近从一个特定的优化任务中得出的个人结论是:

  • clang比gcc
  • 更好地实现了自动矢量化
  • clang 10的自动矢量化效果优于clang 8
  • clang对特定Cortex内核的调优令人印象深刻
  • 有用的clang标志:-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输出,发现自动矢量化代码的弱点,然后从那里开始工作。

    09-09 18:36