On 10/06/2013 01:34 PM, Kjetil Matheussen wrote:
I want to detect INFs and NANs in my DSP graph to
avoid having
them spread and cause various trouble.
Here is the straight forward way:
int i;
for (i=0;i<num_samples;i++)
if (!isfinite(samples[i])) break
if(i!=num_samples)
error();
But is this as efficient as we get it?
Probably. Unless you start to dive into CPU specifics and wander off to
assembly.
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.
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.
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).
brainstormingly yours,
robin