Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flushing denormalised numbers to zero

I've scoured the web to no avail.

Is there a way for Xcode and Visual C++ to treat denormalised numbers as 0? I would have thought there's an option in the IDE preferences to turn on this option but can't seem to find it.

I'm doing some cross-platform audio stuff and need to stop certain processors hogging resources.

Cheers

like image 602
Adam Avatar asked Jul 26 '12 14:07

Adam


2 Answers

You're looking for a platform-defined way to set FTZ and/or DAZ in the MXCSR register (on x86 with SSE or x86-64); see https://stackoverflow.com/a/2487733/567292

Usually this is called something like _controlfp; Microsoft documentation is at http://msdn.microsoft.com/en-us/library/e9b52ceh.aspx

You can also use the _MM_SET_FLUSH_ZERO_MODE macro: http://msdn.microsoft.com/en-us/library/a8b5ts9s(v=vs.71).aspx - this is probably the most cross-platform portable method.

like image 129
ecatmur Avatar answered Nov 10 '22 19:11

ecatmur


For disabling denormals globally I use these 2 macros:

//warning these macros has to be used in the same scope
#define MXCSR_SET_DAZ_AND_FTZ \
int oldMXCSR__ = _mm_getcsr(); /*read the old MXCSR setting */ \
int newMXCSR__ = oldMXCSR__ | 0x8040; /* set DAZ and FZ bits */ \
_mm_setcsr( newMXCSR__ ); /*write the new MXCSR setting to the MXCSR */ 

#define MXCSR_RESET_DAZ_AND_FTZ \
/*restore old MXCSR settings to turn denormals back on if they were on*/ \
_mm_setcsr( oldMXCSR__ ); 

I call the first one at the beginning of the process and the second at the end. Unfortunately this seems to not works well on Windows.

To flush denormals locally I use this

const Float32 k_DENORMAL_DC = 1e-25f;
inline void FlushDenormalToZero(Float32& ioFloat) 
{ 
    ioFloat += k_DENORMAL_DC;
    ioFloat -= k_DENORMAL_DC;    
} 
like image 31
Kevin MOLCARD Avatar answered Nov 10 '22 20:11

Kevin MOLCARD