我试图在我的CPP项目中使用Project NE10执行FFT
- > signal manipulation
- > Inverse FFT
并将复杂输出转换为幅度和IFFT的相位,反之亦然。但是根据基准测试,我的C ++代码的性能不如支持SIMD的NE10代码。由于我没有手臂组装的经验,我正在寻找一些帮助来为未经优化的C模块编写霓虹灯代码。例如,在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]);
}
其中input
是C个结构的数组(对于复数值),amplitudes
&amp; phases
是float
数组。
上述块(O(n) complexity)
对于8192个区块大约需要0.6ms,而由于SIMD操作,NE10 FFT (O(n*log(n)) complexity)
仅需要0.1ms。从我到目前为止在StackOverflow和其他地方读到的内容来看,内在函数不值得付出努力,所以我只是尝试使用arm neon。
答案 0 :(得分:1)
如果满足近似要求,则可以将NEON用于触发函数。我没有隶属关系,但是有一个实现here,该实现使用内在函数创建精确到许多小数位的矢量化sin / cos函数,这些函数的性能远远优于简单调用sinf
等(基准由作者)。
该代码特别适合您的极坐标到直角坐标计算,因为它同时生成sin和cos结果。它可能不适用于绝对精度至关重要的事物,但对于与频域音频处理有关的事物,通常情况并非如此。
答案 1 :(得分:0)
据我所知,NEON不支持几何函数(sin,cos)的向量运算。但是,当然你可以改进你的代码。作为变体,您可以使用函数sin和余弦的预先计算值表。它可以显着改善性能。
关于NEON使用内在函数。我试图使用它们,但在大多数情况下,它们给出了几乎相同的结果(对于现代编译器)。但是使用汇编程序会更加劳动密集。主要的性能改进是通过对数据(加载,存储)的正确操作和使用向量指令给出的,但这些操作可以使用内在函数来执行。
当然,如果你想实现100%的CPU利用率,你有时需要使用汇编程序。但这种情况很少见。