Title: [133653] trunk/Source
Revision
133653
Author
[email protected]
Date
2012-11-06 12:10:46 -0800 (Tue, 06 Nov 2012)

Log Message

Speed up TransformationMatrix::multiply() on modern ARM
https://bugs.webkit.org/show_bug.cgi?id=101084

Reviewed by Gavin Barraclough.

Source/WebCore: 

The main improvements are:
-Store the full source matrix in the registers d16 to d31. This way we avoid going
 back and forth to memory to use the operands.
 Since the full matrix is in register, we can also directly modify the memory of m_matrix,
 we no longer need the temporary matrix memcopied at the end.
-Use of LoadMultiple and StoreMultiple to load-store the matrix parameters.
-Use Multiply-Accumulate instead of VMUL followed by VADD. This half the number of instruction.
-On regular ARMv7, using a loop to reuse the same code for each row also improve the performance.

Depending on the hardware, the new code takes 20% to 42% less time than the basic implementation.

* platform/graphics/transforms/TransformationMatrix.cpp:
(WebCore::TransformationMatrix::multiply):
* platform/graphics/transforms/TransformationMatrix.h:
(TransformationMatrix):

Source/WTF: 

* wtf/Platform.h:
Add CPU(ARM_VFP) for detecting VFP availability.
Add CPU(APPLE_ARMV7S) for the Apple ARMv7S architecture.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (133652 => 133653)


--- trunk/Source/WTF/ChangeLog	2012-11-06 20:08:19 UTC (rev 133652)
+++ trunk/Source/WTF/ChangeLog	2012-11-06 20:10:46 UTC (rev 133653)
@@ -1,3 +1,14 @@
+2012-11-06  Benjamin Poulain  <[email protected]>
+
+        Speed up TransformationMatrix::multiply() on modern ARM
+        https://bugs.webkit.org/show_bug.cgi?id=101084
+
+        Reviewed by Gavin Barraclough.
+
+        * wtf/Platform.h:
+        Add CPU(ARM_VFP) for detecting VFP availability.
+        Add CPU(APPLE_ARMV7S) for the Apple ARMv7S architecture.
+
 2012-11-06  Laszlo Gombos  <[email protected]>
 
         Refactor setting TEXTURE_MAPPER_GL

Modified: trunk/Source/WTF/wtf/Platform.h (133652 => 133653)


--- trunk/Source/WTF/wtf/Platform.h	2012-11-06 20:08:19 UTC (rev 133652)
+++ trunk/Source/WTF/wtf/Platform.h	2012-11-06 20:10:46 UTC (rev 133653)
@@ -302,6 +302,14 @@
 #define HAVE_ARM_NEON_INTRINSICS 1
 #endif
 
+#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
+#define WTF_CPU_ARM_VFP 1
+#endif
+
+#if defined(__ARM_ARCH_7S__)
+#define WTF_CPU_APPLE_ARMV7S 1
+#endif
+
 #endif /* ARM */
 
 #if CPU(ARM) || CPU(MIPS) || CPU(SH4) || CPU(SPARC)

Modified: trunk/Source/WebCore/ChangeLog (133652 => 133653)


--- trunk/Source/WebCore/ChangeLog	2012-11-06 20:08:19 UTC (rev 133652)
+++ trunk/Source/WebCore/ChangeLog	2012-11-06 20:10:46 UTC (rev 133653)
@@ -1,3 +1,26 @@
+2012-11-06  Benjamin Poulain  <[email protected]>
+
+        Speed up TransformationMatrix::multiply() on modern ARM
+        https://bugs.webkit.org/show_bug.cgi?id=101084
+
+        Reviewed by Gavin Barraclough.
+
+        The main improvements are:
+        -Store the full source matrix in the registers d16 to d31. This way we avoid going
+         back and forth to memory to use the operands.
+         Since the full matrix is in register, we can also directly modify the memory of m_matrix,
+         we no longer need the temporary matrix memcopied at the end.
+        -Use of LoadMultiple and StoreMultiple to load-store the matrix parameters.
+        -Use Multiply-Accumulate instead of VMUL followed by VADD. This half the number of instruction.
+        -On regular ARMv7, using a loop to reuse the same code for each row also improve the performance.
+
+        Depending on the hardware, the new code takes 20% to 42% less time than the basic implementation.
+
+        * platform/graphics/transforms/TransformationMatrix.cpp:
+        (WebCore::TransformationMatrix::multiply):
+        * platform/graphics/transforms/TransformationMatrix.h:
+        (TransformationMatrix):
+
 2012-11-06  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r133529 and r133562.

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp (133652 => 133653)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp	2012-11-06 20:08:19 UTC (rev 133652)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp	2012-11-06 20:10:46 UTC (rev 133653)
@@ -971,6 +971,149 @@
 //
 TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix& mat)
 {
+#if CPU(APPLE_ARMV7S)
+    double* leftMatrix = &(m_matrix[0][0]);
+    const double* rightMatrix = &(mat.m_matrix[0][0]);
+    asm volatile (// First row of leftMatrix.
+        "mov        r3, %[leftMatrix]\n\t"
+        "vld1.64    { d16-d19 }, [%[leftMatrix], :128]!\n\t"
+        "vld1.64    { d0-d3}, [%[rightMatrix], :128]!\n\t"
+        "vmul.f64   d4, d0, d16\n\t"
+        "vld1.64    { d20-d23 }, [%[leftMatrix], :128]!\n\t"
+        "vmla.f64   d4, d1, d20\n\t"
+        "vld1.64    { d24-d27 }, [%[leftMatrix], :128]!\n\t"
+        "vmla.f64   d4, d2, d24\n\t"
+        "vld1.64    { d28-d31 }, [%[leftMatrix], :128]!\n\t"
+        "vmla.f64   d4, d3, d28\n\t"
+
+        "vmul.f64   d5, d0, d17\n\t"
+        "vmla.f64   d5, d1, d21\n\t"
+        "vmla.f64   d5, d2, d25\n\t"
+        "vmla.f64   d5, d3, d29\n\t"
+
+        "vmul.f64   d6, d0, d18\n\t"
+        "vmla.f64   d6, d1, d22\n\t"
+        "vmla.f64   d6, d2, d26\n\t"
+        "vmla.f64   d6, d3, d30\n\t"
+
+        "vmul.f64   d7, d0, d19\n\t"
+        "vmla.f64   d7, d1, d23\n\t"
+        "vmla.f64   d7, d2, d27\n\t"
+        "vmla.f64   d7, d3, d31\n\t"
+        "vld1.64    { d0-d3}, [%[rightMatrix], :128]!\n\t"
+        "vst1.64    { d4-d7 }, [r3, :128]!\n\t"
+
+        // Second row of leftMatrix.
+        "vmul.f64   d4, d0, d16\n\t"
+        "vmla.f64   d4, d1, d20\n\t"
+        "vmla.f64   d4, d2, d24\n\t"
+        "vmla.f64   d4, d3, d28\n\t"
+
+        "vmul.f64   d5, d0, d17\n\t"
+        "vmla.f64   d5, d1, d21\n\t"
+        "vmla.f64   d5, d2, d25\n\t"
+        "vmla.f64   d5, d3, d29\n\t"
+
+        "vmul.f64   d6, d0, d18\n\t"
+        "vmla.f64   d6, d1, d22\n\t"
+        "vmla.f64   d6, d2, d26\n\t"
+        "vmla.f64   d6, d3, d30\n\t"
+
+        "vmul.f64   d7, d0, d19\n\t"
+        "vmla.f64   d7, d1, d23\n\t"
+        "vmla.f64   d7, d2, d27\n\t"
+        "vmla.f64   d7, d3, d31\n\t"
+        "vld1.64    { d0-d3}, [%[rightMatrix], :128]!\n\t"
+        "vst1.64    { d4-d7 }, [r3, :128]!\n\t"
+
+        // Third row of leftMatrix.
+        "vmul.f64   d4, d0, d16\n\t"
+        "vmla.f64   d4, d1, d20\n\t"
+        "vmla.f64   d4, d2, d24\n\t"
+        "vmla.f64   d4, d3, d28\n\t"
+
+        "vmul.f64   d5, d0, d17\n\t"
+        "vmla.f64   d5, d1, d21\n\t"
+        "vmla.f64   d5, d2, d25\n\t"
+        "vmla.f64   d5, d3, d29\n\t"
+
+        "vmul.f64   d6, d0, d18\n\t"
+        "vmla.f64   d6, d1, d22\n\t"
+        "vmla.f64   d6, d2, d26\n\t"
+        "vmla.f64   d6, d3, d30\n\t"
+
+        "vmul.f64   d7, d0, d19\n\t"
+        "vmla.f64   d7, d1, d23\n\t"
+        "vmla.f64   d7, d2, d27\n\t"
+        "vmla.f64   d7, d3, d31\n\t"
+        "vld1.64    { d0-d3}, [%[rightMatrix], :128]\n\t"
+        "vst1.64    { d4-d7 }, [r3, :128]!\n\t"
+
+        // Fourth and last row of leftMatrix.
+        "vmul.f64   d4, d0, d16\n\t"
+        "vmla.f64   d4, d1, d20\n\t"
+        "vmla.f64   d4, d2, d24\n\t"
+        "vmla.f64   d4, d3, d28\n\t"
+
+        "vmul.f64   d5, d0, d17\n\t"
+        "vmla.f64   d5, d1, d21\n\t"
+        "vmla.f64   d5, d2, d25\n\t"
+        "vmla.f64   d5, d3, d29\n\t"
+
+        "vmul.f64   d6, d0, d18\n\t"
+        "vmla.f64   d6, d1, d22\n\t"
+        "vmla.f64   d6, d2, d26\n\t"
+        "vmla.f64   d6, d3, d30\n\t"
+
+        "vmul.f64   d7, d0, d19\n\t"
+        "vmla.f64   d7, d1, d23\n\t"
+        "vmla.f64   d7, d2, d27\n\t"
+        "vmla.f64   d7, d3, d31\n\t"
+        "vst1.64    { d4-d7 }, [r3, :128]\n\t"
+        : [leftMatrix]"+r"(leftMatrix), [rightMatrix]"+r"(rightMatrix)
+        :
+        : "memory", "r3", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31");
+#elif CPU(ARM_VFP) && PLATFORM(IOS)
+
+#define MATRIX_MULTIPLY_ONE_LINE \
+    "vldmia.64  %[rightMatrix]!, { d0-d3}\n\t" \
+    "vmul.f64   d4, d0, d16\n\t" \
+    "vmla.f64   d4, d1, d20\n\t" \
+    "vmla.f64   d4, d2, d24\n\t" \
+    "vmla.f64   d4, d3, d28\n\t" \
+    \
+    "vmul.f64   d5, d0, d17\n\t" \
+    "vmla.f64   d5, d1, d21\n\t" \
+    "vmla.f64   d5, d2, d25\n\t" \
+    "vmla.f64   d5, d3, d29\n\t" \
+    \
+    "vmul.f64   d6, d0, d18\n\t" \
+    "vmla.f64   d6, d1, d22\n\t" \
+    "vmla.f64   d6, d2, d26\n\t" \
+    "vmla.f64   d6, d3, d30\n\t" \
+    \
+    "vmul.f64   d7, d0, d19\n\t" \
+    "vmla.f64   d7, d1, d23\n\t" \
+    "vmla.f64   d7, d2, d27\n\t" \
+    "vmla.f64   d7, d3, d31\n\t" \
+    "vstmia.64  %[leftMatrix]!, { d4-d7 }\n\t"
+
+    double* leftMatrix = &(m_matrix[0][0]);
+    const double* rightMatrix = &(mat.m_matrix[0][0]);
+    // We load the full m_matrix at once in d16-d31.
+    asm volatile("vldmia.64  %[leftMatrix], { d16-d31 }\n\t"
+                 :
+                 : [leftMatrix]"r"(leftMatrix)
+                 : "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31");
+    for (unsigned i = 0; i < 4; ++i) {
+        asm volatile(MATRIX_MULTIPLY_ONE_LINE
+                     : [leftMatrix]"+r"(leftMatrix), [rightMatrix]"+r"(rightMatrix)
+                     :
+                     : "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7");
+    }
+#undef MATRIX_MULTIPLY_ONE_LINE
+
+#else
     Matrix4 tmp;
     
     tmp[0][0] = (mat.m_matrix[0][0] * m_matrix[0][0] + mat.m_matrix[0][1] * m_matrix[1][0]
@@ -1010,6 +1153,7 @@
                + mat.m_matrix[3][2] * m_matrix[2][3] + mat.m_matrix[3][3] * m_matrix[3][3]);
     
     setMatrix(tmp);
+#endif
     return *this;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h (133652 => 133653)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h	2012-11-06 20:08:19 UTC (rev 133652)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h	2012-11-06 20:10:46 UTC (rev 133653)
@@ -72,7 +72,11 @@
 class TransformationMatrix {
     WTF_MAKE_FAST_ALLOCATED;
 public:
+#if CPU(APPLE_ARMV7S)
+    typedef double Matrix4[4][4] __attribute__((aligned (16)));
+#else
     typedef double Matrix4[4][4];
+#endif
 
     TransformationMatrix() { makeIdentity(); }
     TransformationMatrix(const AffineTransform& t);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to