diff options
author | adrian.belgun@intel.com <adrian.belgun@intel.com> | 2015-09-16 11:36:34 +0000 |
---|---|---|
committer | adrian.belgun@intel.com <adrian.belgun@intel.com> | 2015-09-16 11:36:34 +0000 |
commit | b71875d54d005a479e094ee24327a179ff690c74 (patch) | |
tree | 8875129cf79d0cedd022d704488ec66b51db4c4f | |
parent | a625677974af878be80eab614ab077961d81d155 (diff) | |
download | chromium_src-b71875d54d005a479e094ee24327a179ff690c74.zip chromium_src-b71875d54d005a479e094ee24327a179ff690c74.tar.gz chromium_src-b71875d54d005a479e094ee24327a179ff690c74.tar.bz2 |
SSE2 Optimization for ParamEvent::LinearRampToValue
Optimized with SSE2 and obtained 4.1x speedup.
Standard: 1.516468 seconds
SSE2 (fp32): 0.074148 seconds
Speedup (fp32): 20.451796
Due to multiple additions with a small vInc, some divergences appear versus the serialized version. Test adjusted accordingly.
BUG=522382
TEST=Run webaudio/audioparam-linearRampToValueAtTime.html
Review URL: https://codereview.chromium.org/1299553004
git-svn-id: svn://svn.chromium.org/blink/trunk@202338 bbb929c8-8fbe-4397-9dbb-9b2b20218538
-rw-r--r-- | third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-loop-points-expected.wav | bin | 0 -> 317564 bytes | |||
-rw-r--r-- | third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-playbackrate-expected.wav | bin | 0 -> 317564 bytes | |||
-rw-r--r-- | third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-loop-points-expected.wav | bin | 0 -> 317564 bytes | |||
-rw-r--r-- | third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-playbackrate-expected.wav | bin | 0 -> 317564 bytes | |||
-rw-r--r-- | third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html | 2 | ||||
-rw-r--r-- | third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp | 27 |
6 files changed, 27 insertions, 2 deletions
diff --git a/third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-loop-points-expected.wav b/third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-loop-points-expected.wav Binary files differnew file mode 100644 index 0000000..72b09d8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-loop-points-expected.wav diff --git a/third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-playbackrate-expected.wav b/third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-playbackrate-expected.wav Binary files differnew file mode 100644 index 0000000..8b9802f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/webaudio/audiobuffersource-playbackrate-expected.wav diff --git a/third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-loop-points-expected.wav b/third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-loop-points-expected.wav Binary files differnew file mode 100644 index 0000000..72b09d8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-loop-points-expected.wav diff --git a/third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-playbackrate-expected.wav b/third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-playbackrate-expected.wav Binary files differnew file mode 100644 index 0000000..8b9802f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/webaudio/audiobuffersource-playbackrate-expected.wav diff --git a/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html b/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html index 6efe7a6..1afab67 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioparam-linearRampToValueAtTime.html @@ -25,7 +25,7 @@ description("Test AudioParam linearRampToValueAtTime() functionality."); var numberOfTests = 100; // Max allowed difference between the rendered data and the expected result. -var maxAllowedError = 6.5e-7; +var maxAllowedError = 7.51e-7; // Set the gain node value to the specified value at the specified time. function setValue(value, time) diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp index ae6c2ba..c1c9f73 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp @@ -359,9 +359,34 @@ float AudioParamTimeline::valuesForTimeRangeImpl( // First handle linear and exponential ramps which require looking ahead to the next event. if (nextEventType == ParamEvent::LinearRampToValue) { + const float valueDelta = value2 - value1; +#if CPU(X86) || CPU(X86_64) + // Minimize in-loop operations. Calculate starting value and increment. Next step: value += inc. + // value = value1 + (currentTime - time1) * k * (value2 - value1); + // inc = sampleFrameTimeIncr * k * (value2 - value1); + // Resolve recursion by expanding constants to achieve a 4-step loop unrolling. + // value = value1 + ((currentTime - time1) + i * sampleFrameTimeIncr) * k * (value2 -value1), i in 0..3 + __m128 vValue = _mm_mul_ps(_mm_set_ps1(sampleFrameTimeIncr), _mm_set_ps(3, 2, 1, 0)); + vValue = _mm_add_ps(vValue, _mm_set_ps1(currentTime - time1)); + vValue = _mm_mul_ps(vValue, _mm_set_ps1(k * valueDelta)); + vValue = _mm_add_ps(vValue, _mm_set_ps1(value1)); + __m128 vInc = _mm_set_ps1(4 * sampleFrameTimeIncr * k * valueDelta); + + // Truncate loop steps to multiple of 4. + unsigned fillToFrameTrunc = writeIndex + ((fillToFrame - writeIndex) / 4) * 4; + // Compute final time. + currentTime += sampleFrameTimeIncr * (fillToFrameTrunc - writeIndex); + // Process 4 loop steps. + for (; writeIndex < fillToFrameTrunc; writeIndex += 4) { + _mm_storeu_ps(values + writeIndex, vValue); + vValue = _mm_add_ps(vValue, vInc); + } +#endif + // Serially process remaining values. for (; writeIndex < fillToFrame; ++writeIndex) { float x = (currentTime - time1) * k; - value = (1 - x) * value1 + x * value2; + // value = (1 - x) * value1 + x * value2; + value = value1 + x * valueDelta; values[writeIndex] = value; currentTime += sampleFrameTimeIncr; } |