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;