On Sun, Oct 6, 2013 at 5:01 PM, Robin Gareus <robin(a)gareus.org> wrote:
I'm
wondering if comparing samples using for instance SIMD
instructions, for instance, could make it around 4 times faster,
Something like this:
for(i=0;i<num_samples;i++)
if(samples[i]!=samples[i]))
break;
where the samples[i]!=samples[i] test would succeed
You probably already know that, but be careful with this when using
optimizations with this comparison. -ffast-math may void IEEE compat.
I didn't know that. Thank you.
if it was a
nan or inf, since INFs and NANs don't behave normally.
I don't think this particular example works though (?),
but perhaps something similar could?
Anyone doing something like this?
In my case it's not only about detecting, but also flushing them to
zero. Depending on what is appropriate for DSP at hand (meters.lv2) I
settled on using math.h's isnan(), !isfinite() or simply adding
something (to minus infinite).
While that's probably not optimal it is portable and architecture
independent, and I don't notice any significant DSP load caused by it.
Yeah, it would probably make a lot more sense time-vice to spend
my time making the DSP graph run on several CPUs, rather than on this
optimization.
BTW gcc does not vectorize the isnan/isfinite loop that you've posted:
"control flow in loop" (i386, gcc 4.7.2). No dice when replacing the
break statement in the loop with v |= isfinite(); either. But it
unrolls the loop at least.
Another idea: add the signal (using SSE). If one of the summands is NaN,
the result will be Nan. -- that should effectively take less CPU
(assuming that NaN is non the common case).
Thank you, guess there are some opportunities there.
To be honest though, I hoped that someone had some read-made
code I could use. :-)
But brainstorming further, it probably works to combine the peak finding routine
(which is run on all signals) with the nan/inf-detection:
static float RT_get_max_val(float *array, int num_elements){
float ret=0.0f;
float minus_ret = 0.0f;
for(int i=0;i<num_elements;i++){
float val = array[i];
if(val>ret){
ret=val;
minus_ret = -val;
}else if (val<minus_ret){
ret = -val;
minus_ret = val;
}
}
// NAN/INF code here:
if(!isfinite(ret))
error();
return ret;
}