浮点数组的abs-max速度更快

Eri*_*_DE 9 c++ optimization performance signal-processing

我需要实时绘制音频峰值表.每秒最少44100个样本,最少40个流.每个缓冲区介于64到1024个样本之间.我需要从每个缓冲区中获取最大值.(然后通过一种低通滤波器馈送,并以约20ms的间隔绘制.)

for(int i = 0; i < numSamples; i++)
{ 
      absMaxOfBuffer = MAX( fabs( buffer[i] ), absMaxOfBuffer);
}
Run Code Online (Sandbox Code Playgroud)

这就是我现在这样做的方式.我想更快地做到这一点.缓冲区的浮点数在-1到1范围内,因此是晶圆厂.

问题,是否有一些棘手的comp-sci quicksort-esque方式更快地做到这一点?

如果不这样,无分支ABS和MAX用于浮点数,它们是否存在?

编辑:主要平台是Linux/gcc,但计划一个Windows端口(可能是mingw).

编辑,第二个:
我接受了onebyone,因为关于实际的算法结构,这是问题的核心.
我会尝试将循环展开到四个,将符号位置零,然后使用SSE(maxps指令)获取最大值,看看是否不会剥离香蕉.感谢您的建议,我已经投票给了你们中的一些人,作为参赛者.:)

Ste*_*sop 5

对于IEEE浮点数来说,晶圆厂和比较都非常快(例如,原则上是单整数运算).

如果编译器没有内联这两个操作,那么要么直接进行操作,要么找到您的体系结构的实现并自行内联.

你可以得到一些事实,即积极的 IEEE浮点数与具有相同位模式的整数的顺序相同.那是,

f > g   iff   *(int*)&f > *(int*)&g
Run Code Online (Sandbox Code Playgroud)

因此,一旦你完成了工作,我认为int的无分支max也适用于float(假设它们的大小当然相同).有一个解释为什么这在这里工作:http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.但是你的编译器已经知道了这一切,你的CPU也是如此,所以它可能没有任何区别.

没有复杂性 - 更快的方式.你的算法已经是O(n),你无法击败它并仍然看着每个样本.

我猜你的处理器的SIMD(即英特尔的SSE2)可能会有一些东西,它可以通过在每个时钟周期处理比代码更多的数据来提供帮助.但我不知道是什么.如果有,那么很可能会快几倍.

您可能可以在多核CPU上并行化,尤其是因为您无论如何都要处理40个独立的流.这将充其量只是一些因素."只是"启动适当数量的额外线程,在它们之间拆分工作,并使用最轻量级的原语来指示它们何时完成(可能是线程障碍).我不太清楚你是否正在绘制所有40个流的最大值,或者是每个流的最大值,所以也许你实际上并不需要同步工作线程,除了确保结果传递到下一个阶段没有数据损坏.

可能值得看看反汇编,看看编译器已经展开了多少循环.尝试展开一点,看看是否有任何区别.

要考虑的另一件事是你得到了多少缓存未命中,以及是否可以通过给缓存提供一些线索来减少数量,以便它可以提前加载正确的页面.但我没有这方面的经验,我也不会抱太大希望.__builtin_prefetch是gcc的神奇咒语,我猜第一个实验就像是"在进入这个块的循环之前预取下一个块的开头".

您目前所需速度的百分比是多少?或者是"尽可能快"的情况?