Title: [109476] trunk/Source/WebCore
Revision
109476
Author
[email protected]
Date
2012-03-01 18:00:07 -0800 (Thu, 01 Mar 2012)

Log Message

SSE optimization for vsvesq and vmaxmgv
https://bugs.webkit.org/show_bug.cgi?id=77950

Patch by Xingnan Wang <[email protected]> on 2012-03-01
Reviewed by Chris Rogers.

Achieved the performance of 3.7x on vsvesq and 4.1x on vmaxmgv.

* platform/audio/VectorMath.cpp:
(WebCore::VectorMath::vsvesq):
(WebCore::VectorMath::vmaxmgv):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (109475 => 109476)


--- trunk/Source/WebCore/ChangeLog	2012-03-02 01:57:07 UTC (rev 109475)
+++ trunk/Source/WebCore/ChangeLog	2012-03-02 02:00:07 UTC (rev 109476)
@@ -1,3 +1,16 @@
+2012-03-01  Xingnan Wang  <[email protected]>
+
+        SSE optimization for vsvesq and vmaxmgv
+        https://bugs.webkit.org/show_bug.cgi?id=77950
+
+        Reviewed by Chris Rogers.
+
+        Achieved the performance of 3.7x on vsvesq and 4.1x on vmaxmgv.
+
+        * platform/audio/VectorMath.cpp:
+        (WebCore::VectorMath::vsvesq):
+        (WebCore::VectorMath::vmaxmgv):
+
 2012-03-01  Luke Macpherson   <[email protected]>
 
         Handle CSSPropertyBoxSizing in CSSStyleApplyProperty.
@@ -9963,7 +9976,6 @@
         (WebCore::ContainerNode::insertBefore):
         (WebCore::ContainerNode::replaceChild):
         (WebCore::ContainerNode::removeChild):
-
 2012-02-22  Dmitry Lomov  <[email protected]>
 
         [JSC] Implement ArrayBuffer and typed array cloning in JSC

Modified: trunk/Source/WebCore/platform/audio/VectorMath.cpp (109475 => 109476)


--- trunk/Source/WebCore/platform/audio/VectorMath.cpp	2012-03-02 01:57:07 UTC (rev 109475)
+++ trunk/Source/WebCore/platform/audio/VectorMath.cpp	2012-03-02 02:00:07 UTC (rev 109476)
@@ -117,7 +117,7 @@
     if ((sourceStride == 1) && (destStride == 1)) {
         float k = *scale;
 
-        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed seperately.
+        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
         while ((reinterpret_cast<uintptr_t>(sourceP) & 0x0F) && n) {
             *destP += k * *sourceP;
             sourceP++;
@@ -125,9 +125,9 @@
             n--;
         }
 
-        // Now the sourceP address aligned and start to apply SSE.
+        // Now the sourceP is aligned, use SSE.
         int tailFrames = n % 4;
-        float* endP = destP + n - tailFrames;
+        const float* endP = destP + n - tailFrames;
 
         __m128 pSource;
         __m128 dest;
@@ -172,7 +172,7 @@
         int n = framesToProcess;
         float k = *scale;
 
-        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed seperately.
+        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
         while ((reinterpret_cast<size_t>(sourceP) & 0x0F) && n) {
             *destP = k * *sourceP;
             sourceP++;
@@ -237,7 +237,7 @@
 
         int n = framesToProcess;
 
-        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed seperately.
+        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
         while ((reinterpret_cast<size_t>(source1P) & 0x0F) && n) {
             *destP = *source1P + *source2P;
             source1P++;
@@ -335,8 +335,7 @@
 
 #ifdef __SSE2__
     if ((sourceStride1 == 1) && (sourceStride2 == 1) && (destStride == 1)) {
-
-        // If the source1P address is not 16-byte aligned, the first several frames (at most three) should be processed seperately.
+        // If the source1P address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
         while ((reinterpret_cast<uintptr_t>(source1P) & 0x0F) && n) {
             *destP = *source1P * *source2P;
             source1P++;
@@ -347,7 +346,7 @@
 
         // Now the source1P address aligned and start to apply SSE.
         int tailFrames = n % 4;
-        float* endP = destP + n - tailFrames;
+        const float* endP = destP + n - tailFrames;
         __m128 pSource1;
         __m128 pSource2;
         __m128 dest;
@@ -430,9 +429,40 @@
 
 void vsvesq(const float* sourceP, int sourceStride, float* sumP, size_t framesToProcess)
 {
-    // FIXME: optimize for SSE
     int n = framesToProcess;
     float sum = 0;
+
+#ifdef __SSE2__ 
+    if (sourceStride == 1) { 
+        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately. 
+        while ((reinterpret_cast<uintptr_t>(sourceP) & 0x0F) && n) { 
+            float sample = *sourceP; 
+            sum += sample * sample; 
+            sourceP++; 
+            n--; 
+        } 
+ 
+        // Now the sourceP is aligned, use SSE.
+        int tailFrames = n % 4; 
+        const float* endP = sourceP + n - tailFrames; 
+        __m128 source; 
+        __m128 mSum = _mm_setzero_ps(); 
+ 
+        while (sourceP < endP) { 
+            source = _mm_load_ps(sourceP); 
+            source = _mm_mul_ps(source, source); 
+            mSum = _mm_add_ps(mSum, source); 
+            sourceP += 4; 
+        } 
+ 
+        // Summarize the SSE results. 
+        const float* groupSumP = reinterpret_cast<float*>(&mSum); 
+        sum += groupSumP[0] + groupSumP[1] + groupSumP[2] + groupSumP[3]; 
+ 
+        n = tailFrames; 
+    } 
+#endif
+
     while (n--) {
         float sample = *sourceP;
         sum += sample * sample;
@@ -445,9 +475,45 @@
 
 void vmaxmgv(const float* sourceP, int sourceStride, float* maxP, size_t framesToProcess)
 {
-    // FIXME: optimize for SSE
     int n = framesToProcess;
     float max = 0;
+
+#ifdef __SSE2__
+    if (sourceStride == 1) {
+        // If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
+        while ((reinterpret_cast<uintptr_t>(sourceP) & 0x0F) && n) {
+            max = std::max(max, fabsf(*sourceP));
+            sourceP++;
+            n--;
+        }
+
+        // Now the sourceP is aligned, use SSE.
+        int tailFrames = n % 4;
+        const float* endP = sourceP + n - tailFrames;
+        __m128 source;
+        __m128 mMax = _mm_setzero_ps();
+        int mask = 0x7FFFFFFF;
+        __m128 mMask = _mm_set1_ps(*reinterpret_cast<float*>(&mask));
+
+        while (sourceP < endP) {
+            source = _mm_load_ps(sourceP);
+            // Calculate the absolute value by anding source with mask, the sign bit is set to 0.
+            source = _mm_and_ps(source, mMask);
+            mMax = _mm_max_ps(mMax, source);
+            sourceP += 4;
+        }
+
+        // Get max from the SSE results.
+        const float* groupMaxP = reinterpret_cast<float*>(&mMax);
+        max = std::max(max, groupMaxP[0]);
+        max = std::max(max, groupMaxP[1]);
+        max = std::max(max, groupMaxP[2]);
+        max = std::max(max, groupMaxP[3]);
+
+        n = tailFrames;
+    }
+#endif
+
     while (n--) {
         max = std::max(max, fabsf(*sourceP));
         sourceP += sourceStride;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to