Denormals

DSP related issues, mathematics, processing and techniques
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Denormals

Post by tulamide »

I'd like to ask about opinions:

If there are denormals, cpu load raises. As an example, in a schematic the idle load is 0.6%. With denormals occuring the load raises to the same value as playing a note, 1.8% in this case. So, denormal remover is the solution, right? Well...
Introducing denormal remover adds to the cpu load, too. With that module the idle load raises from 0.6 to 1%, which is near to double the amount, while not even halving the denormal load. Should it be used nevertheless, or is there a less cpu heavy solution?
"There lies the dog buried" (German saying translated literally)
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Denormals

Post by KG_is_back »

Don't use the stock denormal remover. Rather add a few lines in the code to remove denormals. Algorithms that involve some feedback loops (filters, envelope followers) are prone to denormals.
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Denormals

Post by tulamide »

I see. Thanks KG!
Would it be sufficient to just cut everything (by setting it to 0) below a certain threshold?
"There lies the dog buried" (German saying translated literally)
Xtinct
Posts: 106
Joined: Fri Feb 11, 2011 12:06 am

Re: Denormals

Post by Xtinct »

you could use something like

Code: Select all

out = in&(abs(in)>1e-06);

but I think that's like decapitation to cure a headache :D
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Denormals

Post by KG_is_back »

tulamide wrote:I see. Thanks KG!
Would it be sufficient to just cut everything (by setting it to 0) below a certain threshold?


Yes, that is a common way to do it. In fact RBJ filters have a very efficient way to do it inside.

Code: Select all

float abs=0

stage(0){
  abs = 3.4e38|0.999999|0.1; //this is a bitwise mask that has all bits on except the first (most significant) one
//when you apply this mask via & (and) to a float number, you remove the sign so it is the cheapest way to do abs(x)
}


var = ((var&abs) > 1e-11)&var;

tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Denormals

Post by tulamide »

KG_is_back wrote:Yes, that is a common way to do it. In fact RBJ filters have a very efficient way to do it inside.

Code: Select all

float abs=0

stage(0){
  abs = 3.4e38|0.999999|0.1; //this is a bitwise mask that has all bits on except the first (most significant) one
//when you apply this mask via & (and) to a float number, you remove the sign so it is the cheapest way to do abs(x)
}


var = ((var&abs) > 1e-11)&var;

Everything below -220 dB (1e-11) should indeed not produce any meaningful data, so that should be safe. But is it reliable, too? I mean does the comparison recognize denormals as being denormalized? I'm a bit coinfused beacause I read this article about the topic: http://www.musicdsp.org/files/denormal.pdf
Starting at chapter 3 ("Solutions") there are quite some different ways described. All of them in C++, which is why I don't know how to do that in dsp code. But especially 3.1.1 and 3.1.2 sound like it should be doable somehow. If so, than 3.1.2 should be the fastest method. Would you mind having a look at the pdf?
"There lies the dog buried" (German saying translated literally)
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Denormals

Post by tulamide »

Xtinct wrote:but I think that's like decapitation to cure a headache :D

:lol:
But that's actually what I was thinking of, too.
"There lies the dog buried" (German saying translated literally)
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Denormals

Post by KG_is_back »

tulamide wrote:Everything below -220 dB (1e-11) should indeed not produce any meaningful data, so that should be safe. But is it reliable, too? I mean does the comparison recognize denormals as being denormalized? I'm a bit coinfused beacause I read this article about the topic: http://www.musicdsp.org/files/denormal.pdfStarting at chapter 3 ("Solutions") there are quite some different ways described. All of them in C++, which is why I don't know how to do that in dsp code. But especially 3.1.1 and 3.1.2 sound like it should be doable somehow. If so, than 3.1.2 should be the fastest method. Would you mind having a look at the pdf?


Denormals are not immortal demons... they are numbers like any other. Comparison works for them the same way as normal numbers - you can add them, multiply them and compare them like normal values.

Solution 3.1.1 is terribly inefficient. It is just a stupid way, to compare x with largest denormal value by splitting float into two integers. and then making value zero if its smaller.

Solution 3.1.2 is very simple and elegant, but it not only removes denormals (and very small number as such) - it removes all decimal values below certain point. Because after adding and subtracting the number is rounded.
example:
v=0.000123456789
v=v+0.01
v=v-0.01
now v=0.00012345700

The solution by comparating abs(value) with small number is optimal - it preserves the number in full quality and actually it is identical with solution 3.1.1 if you choose the small value to be next to denormal. In praxis you what to remove value even if it only gets close to denormal range, because further processing can turn it into denormal. Imagine you have a filter that outputs value very close to denormal and you pass that value to amp which makes it even smaller... BOOM denormals...
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Denormals

Post by tulamide »

Thank you very much for this detailed explanation. I could follow it and understand the logic. Finally.

I will use the abs method. Thanks, KG :D
"There lies the dog buried" (German saying translated literally)
tester
Posts: 1786
Joined: Wed Jan 18, 2012 10:52 pm
Location: Poland, internet

Re: Denormals

Post by tester »

Will/would such portion of code change something (CPU usage) in (where in the design where? input?) zdf filters posted somewhere here?
Need to take a break? I have something right for you.
Feel free to donate. Thank you for your contribution.
Post Reply