Arm 霓虹灯代码,用于转换黑白矩形和极轴形状

Arm 霓虹灯代码,用于转换黑白矩形和极轴形状,arm,simd,neon,Arm,Simd,Neon,我正在尝试在我的CPP项目中使用FFT->信号处理->逆FFT,并将复输出转换为FFT的振幅和相位,反之亦然。但是我的C++代码的性能不如基准的SIMD启用的NE10代码那么好。由于我没有arm组装的经验,我正在寻找一些帮助来为未经优化的C模块编写neon代码。例如,在IFFT之前,我执行以下操作: for (int bin = 0; bin < NUM_FREQUENCY_BINS; bin++) { input[bin].real = amplitudes[bin] * cos

我正在尝试在我的CPP项目中使用
FFT
->
信号处理
->
逆FFT
,并将复输出转换为FFT的振幅和相位,反之亦然。但是我的C++代码的性能不如基准的SIMD启用的NE10代码那么好。由于我没有arm组装的经验,我正在寻找一些帮助来为未经优化的C模块编写neon代码。例如,在IFFT之前,我执行以下操作:

for (int bin = 0; bin < NUM_FREQUENCY_BINS; bin++) {
    input[bin].real = amplitudes[bin] * cosf(phases[bin]);
    input[bin].imag = amplitudes[bin] * sinf(phases[bin]);
}
for(int-bin=0;bin
其中,
输入
是一个C结构数组(对于复数值),
振幅
相位
浮点
数组


上述块
(O(n)复杂度)
对于8192个存储单元大约需要0.6ms,而由于SIMD操作,NE10 FFT
(O(n*log(n))复杂度)
只需要0.1ms。从我到目前为止在StackOverflow和其他地方所读到的内容来看,内部函数不值得付出努力,因此我只尝试使用arm neon。

正如我所知,neon不支持几何函数(sin,cos)的向量运算。当然,您可以改进代码。作为变量,您可以使用函数正弦和余弦的预计算值表。它可以显著提高性能

关于霓虹灯的使用。我曾尝试使用这两种方法,但在大多数情况下,它们给出的结果几乎相同(对于现代编译器)。但使用if汇编程序更需要劳动。主要的性能改进是通过正确操作数据(加载、存储)和使用向量指令来实现的,但这些操作可以通过使用内部函数来实现


当然,如果您想实现100%的CPU利用率,有时需要使用汇编程序。但这是罕见的情况。

如果你满足于近似,你可以用氖作为三角函数。我不是附属的,但是有一个实现,它使用内部函数创建精确到许多小数位的向量化sin/cos函数,其性能比简单地调用
sinf
等要好得多(基准由作者提供)


该代码特别适合于极坐标到笛卡尔坐标的计算,因为它同时生成正弦和余弦结果。它可能不适用于绝对精度至关重要的情况,但对于与频域音频处理有关的任何事情,通常情况下都不是这样。

内部功能绝对值得付出努力。特别是,您可以将诸如寄存器分配之类的繁琐工作留给编译器,与手写程序集相比,这将提高性能,除非您非常擅长编写程序集,并且知道代码将运行的微体系结构的详细信息。我有一个在循环中显示对
cosf
sinf
的调用。函数调用会产生大量内存开销。这是一个和
cosf
sinf
是相关的,因此计算两者。标准的“C”库具有非常严格的精度(至少这是重点)。。。。两者同时在上面。。。也就是说,你的“信号操纵”可以在极坐标或实坐标/虚坐标上执行,所以你不需要进行这种转换。实际上,你需要做一些数学运算,以使事情保持一致(或者至少这是值得研究的)“卷积”可能是你需要添加到工具箱中的东西?或者至少你的问题的信号处理方面可能很重要;你为什么需要转换?我通过将振幅转换到更高的频率来改变麦克风的输入信号。对我来说,最简单的方法是使用振幅。