Miller,
I'd like to ask for a source code change to deal with denormalized numbers in PD. Inquiries on the PD list have shown that I am not the only one who has found his or her CPU spiking up over 100% whenever any sound in the patch becomes very small, both under Linux and Windows. The problem gets extremely bad when dealing with decaying sounds, such as reverb tails and feedback delays. I have noticed that denormalized numbers are a much more serious problem under Linux, particularly when using a P4 processor, although the problem is not limited to this specific processor.
Research on the web has informed me that hardware manufacturers have no inclination to fix this problem, so the solution must be handled on the software level. Olaf Matthes proposed the following changes to the source code, which should be implemented in both the PD code itself, as well as any in external which might produce denormals:
A fix in terms of changing the source code is to add the following:
#define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0
and add
undenormalise(myfloatvalue);
wherever a calculation might have produced very small values (replace 'myfloatvalue' with the variable that stores the float). There are many many places in the Pd sources (and in every external) where this happens.
Could you please consider implementing this, or a similar bugfix, in a future release of PD?
Thanks for your hard work so far, Derek
Hi Derek, hi all, i've been following a similar discussion on the Max/MSP for Windows list, where Cycling also modified their externals in an appropriate way.
There are some points to keep in mind:
#ifdef excluding the relevant code for OSX build
frequently happen. I'd find it better to introduce an additional external object (like bitsafe in max) which can correct the signal for more occasional denormal situations.
not ideal because of branching. There are some more approaches to the problem, including "quantification"... have a look at the excellent article by Laurent de Soras: http://ldesoras.free.fr/doc/articles/denormal.pdf
greetings, Thomas
----- Original Message ----- From: "derek holzer" derek@x-i.net To: mpuckett@man104-1.ucsd.edu Cc: PD-list@iem.kug.ac.at Sent: Friday, September 19, 2003 11:32 AM Subject: [PD] denormalized numbers bugfix in PD
Miller,
I'd like to ask for a source code change to deal with denormalized numbers in PD. Inquiries on the PD list have shown that I am not the only one who has found his or her CPU spiking up over 100% whenever any sound in the patch becomes very small, both under Linux and Windows. The problem gets extremely bad when dealing with decaying sounds, such as reverb tails and feedback delays. I have noticed that denormalized numbers are a much more serious problem under Linux, particularly when using a P4 processor, although the problem is not limited to this specific processor.
Research on the web has informed me that hardware manufacturers have no inclination to fix this problem, so the solution must be handled on the software level. Olaf Matthes proposed the following changes to the source code, which should be implemented in both the PD code itself, as well as any in external which might produce denormals:
A fix in terms of changing the source code is to add the following:
#define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0
and add
undenormalise(myfloatvalue);
wherever a calculation might have produced very small values (replace 'myfloatvalue' with the variable that stores the float). There are many many places in the Pd sources (and in every external) where this happens.
Could you please consider implementing this, or a similar bugfix, in a future release of PD?
Thanks for your hard work so far, Derek
PD-list mailing list PD-list@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-list
Thomas Grill schrieb:
- i don't think that there are too many places where a denormalisation can
frequently happen. I'd find it better to introduce an additional external object (like bitsafe in max) which can correct the signal for more occasional denormal situations.
This could be an additional option for 'odd' combinations of objects. I've found that some externals (freeverb~, for example) really need denormalisation within the external. Otherwise one single freeverb~ object would block the whole machine. There are also some native Pd object that would need it (e.g. some of the filters do). So I think it would be a good idea to add the code where it is known that denormalisation can happen. The extra CPU load for checking for denormals (where it is likely to find them) is probably less a pain then the 100% CPU spikes that _will_ sooner or later occur otherwise.
Olaf
hi Thomas, Derek, and all,
Pd does actually kill denormals in [send~], [throw~], [line~], [delwrite~], [hip~], [lop~], [bp~], [biquad~], [tabwrite~], and [tabsend~]. Some externs do the same, e.g. cyclone's filters and envelopes.
So, one way to speed things up in a patch would be inserting a s~/r~ or the like, after finding a proper place for them.
Btw, the PD_BADFLOAT macro seems like the main obstacle in trying to make Pd conform to gcc-3.3 (other warnings are plain easy to deal with).
Does anybody know, how to modify it without a performance loss?
Krzysztof
Thomas Grill wrote: ...
There are some points to keep in mind:
- PowerPC processors don't suffer from the problem, so there should be an
#ifdef excluding the relevant code for OSX build
true, there is none in m_pd.h
I'd like to ask for a source code change to deal with denormalized numbers in PD. Inquiries on the PD list have shown that I am not the
Krzysztof Czaja schrieb:
Does anybody know, how to modify it without a performance loss?
Here is what Max/MSP (Windows) uses:
#define IS_DENORM_FLOAT(v) ((((*(unsigned long *)&(v))&0x7f800000)==0)&&((v)!=0.f)) #define IS_DENORM_DOUBLE(v) ((((((unsigned long *)&(v))[1])&0x7fe00000)==0)&&((v)!=0.))
#define IS_NAN_FLOAT(v) (((*(unsigned long *)&(v))&0x7f800000)==0x7f800000) #define IS_NAN_DOUBLE(v) (((((unsigned long *)&(v))[1])&0x7fe00000)==0x7fe00000)
#define IS_DENORM_NAN_FLOAT(v)
(IS_DENORM_FLOAT(v)||IS_NAN_FLOAT(v))
#define IS_DENORM_NAN_DOUBLE(v)
(IS_DENORM_DOUBLE(v)||IS_NAN_DOUBLE(v))
#define FIX_DENORM_FLOAT(v) ((v)=IS_DENORM_FLOAT(v)?0.f:(v))
#define FIX_DENORM_DOUBLE(v)
((v)=IS_DENORM_DOUBLE(v)?0.f:(v))
#define FIX_DENORM_NAN_FLOAT(v)
((v)=IS_DENORM_NAN_FLOAT(v)?0.f:(v))
#define FIX_DENORM_NAN_DOUBLE(v)
((v)=IS_DENORM_NAN_DOUBLE(v)?0.:(v))
thanks Olaf,
in essence, this is the test Pd uses too (just split in two), unfortunately, so gcc-3.3 does not like it either...
Krzysztof
Olaf Matthes wrote:
Krzysztof Czaja schrieb:
Does anybody know, how to modify it without a performance loss?
Here is what Max/MSP (Windows) uses:
#define IS_DENORM_FLOAT(v) ((((*(unsigned long *)&(v))&0x7f800000)==0)&&((v)!=0.f))
...
#define IS_NAN_FLOAT(v) (((*(unsigned long *)&(v))&0x7f800000)==0x7f800000)
OK, I read a bit further and found on the LAD group that I have to invoke "-fno-strict-aliasing" to make this test (and ones like it) work correctly. This may also slow the code down slightly; I'll check that.
cheers Miller
On Fri, Sep 19, 2003 at 01:55:34PM +0200, Krzysztof Czaja wrote:
thanks Olaf,
in essence, this is the test Pd uses too (just split in two), unfortunately, so gcc-3.3 does not like it either...
Krzysztof
Olaf Matthes wrote:
Krzysztof Czaja schrieb:
Does anybody know, how to modify it without a performance loss?
Here is what Max/MSP (Windows) uses:
#define IS_DENORM_FLOAT(v) ((((*(unsigned long *)&(v))&0x7f800000)==0)&&((v)!=0.f))
...
#define IS_NAN_FLOAT(v) (((*(unsigned long *)&(v))&0x7f800000)==0x7f800000)
PD-list mailing list PD-list@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-list
what about throw~ and catch~?
also, what about the diferences between windows and linux in the way denormals are handled. i use the exact same version of PD, 0.36-0, under both systems, but have VERY different results. a patch which hovers nicely at about 35% CPU usage under windows has nasty denormal-explosions under Linux!
this problem is about the only thing that stops me from performing using Linux [a personal goal of mine], so i would be pretty interested in seeing some code-level solution.
derek
Quoting guenter geiger geiger@xdv.org:
On Fri, 19 Sep 2003, Krzysztof Czaja wrote:
hi Thomas, Derek, and all,
Pd does actually kill denormals in [send~], [throw~], [line~], [delwrite~], [hip~], [lop~], [bp~], [biquad~], [tabwrite~], and [tabsend~].
vcf~ should be added then.
Guenter
PD-list mailing list PD-list@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-list
Notice: Please do not send attchments or HTML/Rich Text emails to this address for the time being. My mail provider is kind-of freaking out ;-) Thx.
derek@x-i.net schrieb:
also, what about the diferences between windows and linux in the way denormals are handled. i use the exact same version of PD, 0.36-0, under both systems, but have VERY different results. a patch which hovers nicely at about 35% CPU usage under windows has nasty denormal-explosions under Linux!
This also seems to be compiler related. On Windows there are differences between VC++ 6.0 and Intels C++ compiler (haven't tested VC++ 7.0). Someone once posted a patch that was easily producing these CPU 'explosions' and I tested it with Pd compiled with Intel compiler, the result was much better. There is still a Intel-compiled Pd version on my website, try http://www.akustische-kunst.org/puredata/experimental/pd0.37-test4-win-P4.zi... to see whether it makes a difference for you. Sorry, just 0.37test4 but I could compile a new one if need be.
Dont know how different compilers behave on Linux, maybe you can just give it a try.
Olaf
Hmm, I'd like to see this patch! Maybe I can figure out why linux and windows are acting differently.
I've been checking for denormals, etc., in anything that can be used to make a feedback loop, thus, objects that read/write into buffers, plus ones that have internal feedback (such as filters). I need to add throw~, catch~, and vcf~.
I think I should really be bashing anything under 1e-20 or so to zero; otherwise I don't catch things until they've already gone denormal. I'd like to find a check that finds denormals AND numbers about to go denormal.
Also, since some compilers apparently don't like this test, I think the best thing for me to do is try to turn off whatever specific warning that gets tripped by the test... if someone can tell me a "pragma" or whatever is making ICC (and/or GCC3.3) complain I'll stick it in the code.
I think I'll fix this and a coupe of other problems and put out a 0.37-1 in a week or so.
cheers Miller
On Sat, Sep 20, 2003 at 02:45:20PM +0200, derek@x-i.net wrote:
what about throw~ and catch~?
also, what about the diferences between windows and linux in the way denormals are handled. i use the exact same version of PD, 0.36-0, under both systems, but have VERY different results. a patch which hovers nicely at about 35% CPU usage under windows has nasty denormal-explosions under Linux!
this problem is about the only thing that stops me from performing using Linux [a personal goal of mine], so i would be pretty interested in seeing some code-level solution.
derek
Quoting guenter geiger geiger@xdv.org:
On Fri, 19 Sep 2003, Krzysztof Czaja wrote:
hi Thomas, Derek, and all,
Pd does actually kill denormals in [send~], [throw~], [line~], [delwrite~], [hip~], [lop~], [bp~], [biquad~], [tabwrite~], and [tabsend~].
vcf~ should be added then.
Guenter
PD-list mailing list PD-list@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-list
Notice: Please do not send attchments or HTML/Rich Text emails to this address for the time being. My mail provider is kind-of freaking out ;-) Thx.
PD-list mailing list PD-list@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-list