Re: [LAD] A more efficient way to detect INF and/or NAN in a block of samples

From: Kjetil Matheussen <k.s.matheussen@email-addr-hidden>
Date: Sun Oct 06 2013 - 22:07:24 EEST

On Sun, Oct 6, 2013 at 5:01 PM, Robin Gareus <robin@email-addr-hidden> 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;
}
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Mon Oct 7 08:15:02 2013

This archive was generated by hypermail 2.1.8 : Mon Oct 07 2013 - 08:15:03 EEST