Bug 70140 - Flush denormals to zero on Windows.
Summary: Flush denormals to zero on Windows.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Audio (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-14 14:04 PDT by Raymond Toy
Modified: 2011-10-19 18:51 PDT (History)
4 users (show)

See Also:


Attachments
Patch (7.77 KB, patch)
2011-10-14 14:06 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff
Patch (7.87 KB, patch)
2011-10-14 14:17 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff
Patch (8.66 KB, patch)
2011-10-14 16:28 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff
Patch (8.88 KB, patch)
2011-10-18 09:25 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff
Patch (8.87 KB, patch)
2011-10-18 10:42 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff
Patch (8.81 KB, patch)
2011-10-18 16:04 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff
Patch (8.84 KB, patch)
2011-10-19 10:33 PDT, Raymond Toy
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Raymond Toy 2011-10-14 14:04:47 PDT
Flush denormals to zero on Windows.
Comment 1 Raymond Toy 2011-10-14 14:06:47 PDT
Created attachment 111070 [details]
Patch
Comment 2 WebKit Review Bot 2011-10-14 14:08:44 PDT
Attachment 111070 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/ChangeLog', u'Source/WebCor..." exit_code: 1

Source/WebCore/platform/audio/DenormalDisabler.h:32:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Source/WebCore/ChangeLog:10:  Line contains tab character.  [whitespace/tab] [5]
Source/WebCore/ChangeLog:13:  Line contains tab character.  [whitespace/tab] [5]
Source/WebCore/ChangeLog:14:  Line contains tab character.  [whitespace/tab] [5]
Total errors found: 4 in 3 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 3 Raymond Toy 2011-10-14 14:14:42 PDT
This patch fixes an issue with denormal floats on Windows.  The issue can be seen at http://chromium.googlecode.com/svn/trunk/samples/audio/dj.html.  Drag the leftRhythmEffect slider to the right and then all the way to the left.  You will hear (and see) artifacts.  These are caused by denormal numbers which are very slow to process.

This doesn't happen on Linux or Mac because denormals are flushed to zero by the SSE hardware.  On windows, SSE is not used, and the x87 has no HW support for flushing denormals to zero.

Also, we converted the local variable, gain, from a double to a float to better match the float values of the inputs and outputs so unnecessary conversions are not needed.
Comment 4 Raymond Toy 2011-10-14 14:17:56 PDT
Created attachment 111072 [details]
Patch
Comment 5 WebKit Review Bot 2011-10-14 14:20:35 PDT
Attachment 111072 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/ChangeLog', u'Source/WebCor..." exit_code: 1

Source/WebCore/platform/audio/DenormalDisabler.h:32:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Total errors found: 1 in 3 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 6 Chris Rogers 2011-10-14 15:04:18 PDT
Comment on attachment 111072 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111072&action=review

> Source/WebCore/platform/audio/AudioBus.cpp:34
> +#include "DenormalDisabler.h"

WebKit style is to put one blank line after: #include "AudioBus.h"

> Source/WebCore/platform/audio/AudioBus.cpp:243
> +    float totalDesiredGain = static_cast<float>(m_busGain * targetGain);

Can't we also make "targetGain" and "m_busGain" a float and avoid the static_cast?

This will likely require changing certain other methods to also take "float" arguments

> Source/WebCore/platform/audio/AudioBus.cpp:246
> +    float gain = static_cast<float>(m_isFirstTime ? totalDesiredGain : *lastMixGain);

ditto

> Source/WebCore/platform/audio/AudioBus.cpp:259
> +    const float DezipperRate = 0.005;

doesn't this need to now be 0.005f ?

> Source/WebCore/platform/audio/AudioBus.cpp:269
> +                *destinationL++ = sumL;

probably can avoid the intermediate "sumL" and "sumR" variables and simply assign directly

> Source/WebCore/platform/audio/AudioBus.cpp:282
> +                float sumR = FlushToFloatZero(*destinationR + scaled);

ditto: can avoid sumL and sumR and assign directly

> Source/WebCore/platform/audio/AudioBus.cpp:295
> +                *destinationL++ = sum;

can avoid sum and assign directly

> Source/WebCore/platform/audio/AudioBus.cpp:342
> +    *lastMixGain = static_cast<double>(gain);

Probably best to make "lastMixGain" float instead of double and avoid the static_cast -- this will require all callers of this function to also switch over to float...

> Source/WebCore/platform/audio/DenormalDisabler.h:34
> +#include <math.h>

Header files should not be included inside of "namespace WebCore {"
please move includes to above the namespace

> Source/WebCore/platform/audio/DenormalDisabler.h:38
> +static inline float FlushToFloatZero(float f)

I'm not very fond of the name "FlushToFloatZero" -- I'd suggest including the word "denormal" in the name.
How about: "FlushFloatDenormalToZero"

Also, it's better to have functions like this be in some kind of namespace.  One idea is to move this inline function as a static inline method of DenormalDisabler

> Source/WebCore/platform/audio/DenormalDisabler.h:43
> +#define FlushToFloatZero(f) static_cast<float>(f)

It seems odd that on Windows this is an inline function, and otherwise is a macro -- maybe just have it uniformly be a static inline method of DenormalDisabler
Comment 7 Raymond Toy 2011-10-14 15:40:55 PDT
Comment on attachment 111072 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111072&action=review

>> Source/WebCore/platform/audio/AudioBus.cpp:34
>> +#include "DenormalDisabler.h"
> 
> WebKit style is to put one blank line after: #include "AudioBus.h"

Done.

>> Source/WebCore/platform/audio/AudioBus.cpp:243
>> +    float totalDesiredGain = static_cast<float>(m_busGain * targetGain);
> 
> Can't we also make "targetGain" and "m_busGain" a float and avoid the static_cast?
> 
> This will likely require changing certain other methods to also take "float" arguments

Yes we could.  I just wanted to keep this change self-contained.  But I can go and change the signature and all the callers appropriately.  I'd rather do that in two stages, though: This one for the important fix, and a follow-on with the targetGain and m_busGain change.

>> Source/WebCore/platform/audio/AudioBus.cpp:259
>> +    const float DezipperRate = 0.005;
> 
> doesn't this need to now be 0.005f ?

Done.

>> Source/WebCore/platform/audio/AudioBus.cpp:269
>> +                *destinationL++ = sumL;
> 
> probably can avoid the intermediate "sumL" and "sumR" variables and simply assign directly

Done.

>> Source/WebCore/platform/audio/AudioBus.cpp:282
>> +                float sumR = FlushToFloatZero(*destinationR + scaled);
> 
> ditto: can avoid sumL and sumR and assign directly

Done.

>> Source/WebCore/platform/audio/AudioBus.cpp:295
>> +                *destinationL++ = sum;
> 
> can avoid sum and assign directly

Done.

>> Source/WebCore/platform/audio/AudioBus.cpp:342
>> +    *lastMixGain = static_cast<double>(gain);
> 
> Probably best to make "lastMixGain" float instead of double and avoid the static_cast -- this will require all callers of this function to also switch over to float...

Same comment as for targetGain, above.

>> Source/WebCore/platform/audio/DenormalDisabler.h:34
>> +#include <math.h>
> 
> Header files should not be included inside of "namespace WebCore {"
> please move includes to above the namespace

Done.

>> Source/WebCore/platform/audio/DenormalDisabler.h:38
>> +static inline float FlushToFloatZero(float f)
> 
> I'm not very fond of the name "FlushToFloatZero" -- I'd suggest including the word "denormal" in the name.
> How about: "FlushFloatDenormalToZero"
> 
> Also, it's better to have functions like this be in some kind of namespace.  One idea is to move this inline function as a static inline method of DenormalDisabler

How about FlushDenormalFloatToZero?

I'll move it to a static inline method.

>> Source/WebCore/platform/audio/DenormalDisabler.h:43
>> +#define FlushToFloatZero(f) static_cast<float>(f)
> 
> It seems odd that on Windows this is an inline function, and otherwise is a macro -- maybe just have it uniformly be a static inline method of DenormalDisabler

That's just an implementation detail; just made it obvious there's no impact even on debug builds.  But I won't have a choice if I make it an static inline method.
Comment 8 Raymond Toy 2011-10-14 15:53:20 PDT
Comment on attachment 111072 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111072&action=review

>>> Source/WebCore/platform/audio/AudioBus.cpp:269
>>> +                *destinationL++ = sumL;
>> 
>> probably can avoid the intermediate "sumL" and "sumR" variables and simply assign directly
> 
> Done.

Oops.  Can't do that because the compiler correctly complains that 

*d++ = Flush(*d + gain * *source)

is undefined.  (Because we don't know when d++ happens because there's no sequence point for =.)
Comment 9 Raymond Toy 2011-10-14 16:28:10 PDT
Created attachment 111105 [details]
Patch
Comment 10 WebKit Review Bot 2011-10-14 16:31:22 PDT
Attachment 111105 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/ChangeLog', u'Source/WebCor..." exit_code: 1

Source/WebCore/platform/audio/DenormalDisabler.h:28:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Source/WebCore/platform/audio/DenormalDisabler.h:81:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Total errors found: 2 in 3 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 11 Chris Rogers 2011-10-17 14:25:30 PDT
Hi Ray, several of the fixes marked as "Done" are not actually in the latest patch - could you please re-check.

> > This will likely require changing certain other methods to also take "float" arguments
> 
> Yes we could.  I just wanted to keep this change self-contained.  But I can go and change the signature and all the callers appropriately.  I'd rather do that in two stages, though: This one for the important fix, and a follow-on with the targetGain and m_busGain change.

Ok, but then in that case please add a FIXME here

> > I'm not very fond of the name "FlushToFloatZero" -- I'd suggest including the word "denormal" in the name.
> > How about: "FlushFloatDenormalToZero"
> > 
> > Also, it's better to have functions like this be in some kind of namespace.  One idea is to move this inline function as a static inline method of DenormalDisabler
> 
> How about FlushDenormalFloatToZero?
> 
> I'll move it to a static inline method.

Seems fine to me.

> 
> >> Source/WebCore/platform/audio/DenormalDisabler.h:43
> >> +#define FlushToFloatZero(f) static_cast<float>(f)
> > 
> > It seems odd that on Windows this is an inline function, and otherwise is a macro -- maybe just have it uniformly be a static inline method of DenormalDisabler
> 
> That's just an implementation detail; just made it obvious there's no impact even on debug builds.  But I won't have a choice if I make it an static inline method.

I know, but it's more of a consistency/style readability thing
Comment 12 Chris Rogers 2011-10-17 14:26:55 PDT
Comment on attachment 111105 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111105&action=review

Please look at style errors and address for next patch.

>> Source/WebCore/platform/audio/DenormalDisabler.h:28
>> +#if OS(WIN) && defined(_MSC_VER) && (_M_IX86_FP == 0)
> 
> Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]

Is there any reason we need to include a Windows specific header file here?  It doesn't seem like we have to.  I'd recommend:

#include <wtf/MathExtras.h>
Comment 13 Chris Rogers 2011-10-17 14:27:52 PDT
(In reply to comment #8)
> Oops.  Can't do that because the compiler correctly complains that 
> 
> *d++ = Flush(*d + gain * *source)
> 
> is undefined.  (Because we don't know when d++ happens because there's no sequence point for =.)

This should not be the case - please re-check
Comment 14 Raymond Toy 2011-10-17 16:11:04 PDT
(In reply to comment #13)
> (In reply to comment #8)
> > Oops.  Can't do that because the compiler correctly complains that 
> > 
> > *d++ = Flush(*d + gain * *source)
> > 
> > is undefined.  (Because we don't know when d++ happens because there's no sequence point for =.)
> 
> This should not be the case - please re-check

I changed the lines from 

 float sumL = DenormalDisabler::FlushDenormalFloatToZero(*destinationL + gain * *sourceL++);
               
 *destinationL++ = sumL;

to

 *destinationL++ = DenormalDisabler::FlushDenormalFloatToZero(*destinationL + gain * *sourceL++);

Gcc (linux) complains:

cc1plus: warnings being treated as errors
third_party/WebKit/Source/WebCore/platform/audio/AudioBus.cpp: In member function ‘void WebCore::AudioBus::processWithGainFromMonoStereo(const WebCore::AudioBus&, double*, double, bool)’:
third_party/WebKit/Source/WebCore/platform/audio/AudioBus.cpp:276: error: operation on ‘destinationL’ may be undefined
Comment 15 Chris Rogers 2011-10-17 18:45:46 PDT
Ok, if there's a compile error, then let's leave that for now and see if we can address the other comments.  Seems like we're getting close.
Comment 16 Raymond Toy 2011-10-18 09:25:18 PDT
Created attachment 111451 [details]
Patch
Comment 17 WebKit Review Bot 2011-10-18 09:28:13 PDT
Attachment 111451 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/ChangeLog', u'Source/WebCor..." exit_code: 1

Source/WebCore/platform/audio/DenormalDisabler.h:28:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Source/WebCore/platform/audio/DenormalDisabler.h:80:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Total errors found: 2 in 3 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 18 Raymond Toy 2011-10-18 09:29:37 PDT
All review comments should be addressed now.  My apologies for overlooking some fixes from last time.
Comment 19 Kenneth Russell 2011-10-18 10:33:07 PDT
Comment on attachment 111451 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111451&action=review

>> Source/WebCore/platform/audio/DenormalDisabler.h:28
>> +#if OS(WINDOWS) && COMPILER(MSVC) && (_M_IX86_FP == 0)
> 
> Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]

To satisfy the style queue the last expression should be written as (!_M_IX86_FP). Here and below.
Comment 20 Chris Rogers 2011-10-18 10:41:52 PDT
Comment on attachment 111451 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111451&action=review

>>> Source/WebCore/platform/audio/DenormalDisabler.h:28
>>> +#if OS(WINDOWS) && COMPILER(MSVC) && (_M_IX86_FP == 0)
>> 
>> Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
> 
> To satisfy the style queue the last expression should be written as (!_M_IX86_FP). Here and below.

Actually, just to make things simpler and more readable I would recommend removing the #if

It's true that it'll include an unneeded include file on some platforms, but it seems worth the cost due to readability.  What do you think Ken?
Comment 21 Raymond Toy 2011-10-18 10:42:34 PDT
Created attachment 111467 [details]
Patch
Comment 22 Kenneth Russell 2011-10-18 11:35:15 PDT
Comment on attachment 111467 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111467&action=review

Code looks good overall but there's a small naming convention issue that needs to be fixed before commit.

Also, please mark subsequent patches cq? if you'd like them submitted to the commit queue after review.

> Source/WebCore/platform/audio/DenormalDisabler.h:51
> +    static inline float FlushDenormalFloatToZero(float f)

This should be "flushDenormalFloatToZero"; WebKit naming convention is camelCase for methods. See http://www.webkit.org/coding/coding-style.html .
Comment 23 Raymond Toy 2011-10-18 16:04:52 PDT
Created attachment 111519 [details]
Patch
Comment 24 Raymond Toy 2011-10-18 16:06:45 PDT
Renamed function to follow webkit style and removed the guards for MathExtras.h.
Comment 25 Kenneth Russell 2011-10-18 17:03:54 PDT
Comment on attachment 111519 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111519&action=review

One more minor process nit. I'm not going to hold this patch up any further since I missed this in the last version, but please keep this in mind for future patches. r=me

> Source/WebCore/ChangeLog:13
> +        (WebCore::FlushToFloatZero):

Please regenerate the ChangeLog after renaming methods. Yes, this is tedious.
Comment 26 Raymond Toy 2011-10-19 10:33:37 PDT
Created attachment 111643 [details]
Patch
Comment 27 Raymond Toy 2011-10-19 10:43:15 PDT
Comment on attachment 111519 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111519&action=review

>> Source/WebCore/ChangeLog:13
>> +        (WebCore::FlushToFloatZero):
> 
> Please regenerate the ChangeLog after renaming methods. Yes, this is tedious.

Fixed.  Sorry about that.
Comment 28 Kenneth Russell 2011-10-19 11:24:15 PDT
Comment on attachment 111643 [details]
Patch

Looks great, thanks. r=me again
Comment 29 WebKit Review Bot 2011-10-19 18:51:23 PDT
Comment on attachment 111643 [details]
Patch

Clearing flags on attachment: 111643

Committed r97912: <http://trac.webkit.org/changeset/97912>
Comment 30 WebKit Review Bot 2011-10-19 18:51:29 PDT
All reviewed patches have been landed.  Closing bug.