用于转换黑白矩形和极坐标形式的霓虹灯代码

时间:2017-02-17 06:44:51

标签: arm simd neon

我试图在我的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; phasesfloat数组。

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

2 个答案:

答案 0 :(得分:1)

如果满足近似要求,则可以将NEON用于触发函数。我没有隶属关系,但是有一个实现here,该实现使用内在函数创建精确到许多小数位的矢量化sin / cos函数,这些函数的性能远远优于简单调用sinf等(基准由作者)。

该代码特别适合您的极坐标到直角坐标计算,因为它同时生成sin和cos结果。它可能不适用于绝对精度至关重要的事物,但对于与频域音频处理有关的事物,通常情况并非如此。

答案 1 :(得分:0)

据我所知,NEON不支持几何函数(sin,cos)的向量运算。但是,当然你可以改进你的代码。作为变体,您可以使用函数sin和余弦的预先计算值表。它可以显着改善性能。

关于NEON使用内在函数。我试图使用它们,但在大多数情况下,它们给出了几乎相同的结果(对于现代编译器)。但是使用汇编程序会更加劳动密集。主要的性能改进是通过对数据(加载,存储)的正确操作和使用向量指令给出的,但这些操作可以使用内在函数来执行。

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