changeset 239:07c4f1a7ddc6

Make DMVector 16 bytes in size (4 floats), add SSE optimizations, move some functions to dmvecmat.h as static inline for speed, etc.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 09 Oct 2012 12:59:09 +0300
parents 9643c517967d
children 61b9cd67cd55
files dmvecmat.c dmvecmat.h vecmattest.c
diffstat 3 files changed, 154 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/dmvecmat.c	Tue Oct 09 06:06:08 2012 +0300
+++ b/dmvecmat.c	Tue Oct 09 12:59:09 2012 +0300
@@ -5,109 +5,6 @@
  * (C) Copyright 2011 Tecnic Software productions (TNSP)
  */
 #include "dmvecmat.h"
-#include <math.h>
-
-
-void dm_vector_copy(DMVector *vd, DMVector *vs)
-{
-    memcpy(vd, vs, sizeof(DMVector));
-}
-
-
-/* Basic vector operations
- */
-void dm_vector_add(DMVector *vr, const DMVector *v2)
-{
-    vr->x += v2->x;
-    vr->y += v2->y;
-    vr->z += v2->z;
-}
-
-
-void dm_vector_add_r(DMVector *vr, const DMVector *v1, const DMVector *v2)
-{
-    vr->x = v1->x + v2->x;
-    vr->y = v1->y + v2->y;
-    vr->z = v1->z + v2->z;
-}
-
-
-void dm_vector_sub(DMVector *vr, const DMVector *v2)
-{
-    vr->x -= v2->x;
-    vr->y -= v2->y;
-    vr->z -= v2->z;
-}
-
-
-void dm_vector_sub_r(DMVector *vr, const DMVector *v1, const DMVector *v2)
-{
-    vr->x = v1->x - v2->x;
-    vr->y = v1->y - v2->y;
-    vr->z = v1->z - v2->z;
-}
-
-
-/* Return vector length
- */
-DMFloat dm_vector_length(const DMVector *vs)
-{
-    return sqrt((vs->x * vs->x) + (vs->y * vs->y) + (vs->z * vs->z));
-}
-
-
-/* Normalize vector
- */
-void dm_vector_normalize(DMVector *vec)
-{
-    DMFloat l = dm_vector_length(vec);
-
-    if (l > 0.0f)
-    {
-        l = 1.0f / l;
-        vec->x *= l;
-        vec->y *= l;
-        vec->z *= l;
-    }
-}
-
-
-/* Scale given vector
- */
-void dm_vector_scale(DMVector * vec, const DMFloat k)
-{
-    vec->x *= k;
-    vec->y *= k;
-    vec->z *= k;
-}
-
-
-/* Returns dot-product of two given vectors
- */
-DMFloat dm_vector_dot(const DMVector *v1, const DMVector *v2)
-{
-    return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z);
-}
-
-
-/* Returns cross-product of two given vectors
- */
-void dm_vector_cross(DMVector *vr, const DMVector *v1, const DMVector *v2)
-{
-    vr->x = (v1->y * v2->z) - (v1->z * v2->y);
-    vr->y = (v1->z * v2->x) - (v1->x * v2->z);
-    vr->z = (v1->x * v2->y) - (v1->y * v2->x);
-}
-
-
-/* Multiply given vector with a matrix
- */
-void dm_vector_mul_by_mat(DMVector *vd, const DMVector *vs, const DMMatrix *mat)
-{
-    vd->x = (vs->x * mat->m[0][0]) + (vs->y * mat->m[1][0]) + (vs->z * mat->m[2][0]);
-    vd->y = (vs->x * mat->m[0][1]) + (vs->y * mat->m[1][1]) + (vs->z * mat->m[2][1]);
-    vd->z = (vs->x * mat->m[0][2]) + (vs->y * mat->m[1][2]) + (vs->z * mat->m[2][2]);
-}
 
 
 /* Multiply list of given vectors with given matrix.
@@ -205,13 +102,3 @@
     mat->m[2][1] = (sy * q) - j;
     mat->m[2][2] = cx * cy;
 }
-
-
-/* Make rotation matrix from given angles (radians)
- */
-void dm_matrix_rot_a(DMMatrix *mat, const DMFloat ax, const DMFloat ay, const DMFloat az)
-{
-    dm_matrix_rot(mat, sin(ax), sin(ay), sin(az), cos(ax), cos(ay), cos(az));
-}
-
-
--- a/dmvecmat.h	Tue Oct 09 06:06:08 2012 +0300
+++ b/dmvecmat.h	Tue Oct 09 12:59:09 2012 +0300
@@ -8,15 +8,17 @@
 #define DMVECMAT_H
 #include "dmlib.h"
 
+#include <math.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define DM_MATRIX_SIZE	(3)
+#define DM_MATRIX_SIZE	(4)
 
 typedef struct
 {
-    DMFloat x, y, z;
+    DMFloat x, y, z, W;
 } DMVector;
 
 typedef	struct
@@ -24,21 +26,6 @@
     DMFloat m[DM_MATRIX_SIZE][DM_MATRIX_SIZE];
 } DMMatrix;
 
-void    dm_vector_copy(DMVector *vd, DMVector *vs);
-
-void    dm_vector_add(DMVector *vr, const DMVector *v2);
-void    dm_vector_add_r(DMVector *vr, const DMVector *v1, const DMVector *v2);
-void    dm_vector_sub(DMVector *vr, const DMVector *v2);
-void    dm_vector_sub_r(DMVector *vr, const DMVector *v1, const DMVector *v2);
-
-DMFloat dm_vector_length(const DMVector *vs);
-void    dm_vector_normalize(DMVector *vs);
-void    dm_vector_scale(DMVector * vec, const DMFloat k);
-DMFloat dm_vector_dot(const DMVector *v1, const DMVector *v2);
-void    dm_vector_cross(DMVector *vr, const DMVector *v1, const DMVector *v2);
-
-
-void    dm_vector_mul_by_mat(DMVector *vd, const DMVector *vs, const DMMatrix *mat);
 void    dm_vector_mul_by_mat_n(DMVector *list, const int nlist, const DMMatrix *mat);
 
 void    dm_matrix_unit(DMMatrix *mat);
@@ -51,8 +38,155 @@
         const DMFloat sx, const DMFloat sy, const DMFloat sz,
         const DMFloat cx, const DMFloat cy, const DMFloat cz);
 
-void    dm_matrix_rot_a(DMMatrix *mat,
-        const DMFloat ax, const DMFloat ay, const DMFloat az);
+
+static inline void dm_vector_copy(DMVector *vd, DMVector *vs)
+{
+    memcpy(vd, vs, sizeof(DMVector));
+}
+
+
+/* Basic vector operations
+ */
+static inline void dm_vector_add(DMVector *vr, const DMVector *v2)
+{
+#ifdef DM_USE_SIMD
+    asm("movups      %2,     %%xmm1\n"
+        "movups      %1,     %%xmm2\n"
+        "addps       %%xmm2, %%xmm1\n"
+        "movups      %%xmm1, %0\n"
+        : "=m" (*vr)
+        : "m" (*vr), "m" (*v2)
+        : "memory", "%xmm1", "%xmm2");
+#else
+    vr->x += v2->x;
+    vr->y += v2->y;
+    vr->z += v2->z;
+#endif
+}
+
+
+static inline void dm_vector_add_r(DMVector *vr, const DMVector *v1, const DMVector *v2)
+{
+#ifdef DM_USE_SIMD
+    asm("movups      %2,     %%xmm1\n"
+        "movups      %1,     %%xmm2\n"
+        "addps       %%xmm2, %%xmm1\n"
+        "movups      %%xmm1, %0\n"
+        : "=m" (*vr)
+        : "m" (*v1), "m" (*v2)
+        : "memory", "%xmm1", "%xmm2");
+#else
+    vr->x = v1->x + v2->x;
+    vr->y = v1->y + v2->y;
+    vr->z = v1->z + v2->z;
+#endif
+}
+
+
+static inline void dm_vector_sub(DMVector *vr, const DMVector *v2)
+{
+#ifdef DM_USE_SIMD
+    asm("movups      %2,     %%xmm1\n"
+        "movups      %1,     %%xmm2\n"
+        "subps       %%xmm2, %%xmm1\n"
+        "movups      %%xmm1, %0\n"
+        : "=m" (*vr)
+        : "m" (*vr), "m" (*v2)
+        : "memory", "%xmm1", "%xmm2");
+#else
+    vr->x -= v2->x;
+    vr->y -= v2->y;
+    vr->z -= v2->z;
+#endif
+}
+
+
+static inline void dm_vector_sub_r(DMVector *vr, const DMVector *v1, const DMVector *v2)
+{
+#ifdef DM_USE_SIMD
+    asm("movups      %2,     %%xmm1\n"
+        "movups      %1,     %%xmm2\n"
+        "subps       %%xmm2, %%xmm1\n"
+        "movups      %%xmm1, %0\n"
+        : "=m" (*vr)
+        : "m" (*v1), "m" (*v2)
+        : "memory", "%xmm1", "%xmm2");
+#else
+    vr->x = v1->x - v2->x;
+    vr->y = v1->y - v2->y;
+    vr->z = v1->z - v2->z;
+#endif
+}
+
+
+/* Returns dot-product of two given vectors
+ */
+static inline DMFloat dm_vector_dot(const DMVector *v1, const DMVector *v2)
+{
+    return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z);
+}
+
+
+/* Return vector length
+ */
+static inline DMFloat dm_vector_length(const DMVector *vs)
+{
+    return sqrt((vs->x * vs->x) + (vs->y * vs->y) + (vs->z * vs->z));
+}
+
+
+/* Normalize vector
+ */
+static inline void dm_vector_normalize(DMVector *vec)
+{
+    DMFloat l = dm_vector_length(vec);
+
+    if (l > 0.0f)
+    {
+        l = 1.0f / l;
+        vec->x *= l;
+        vec->y *= l;
+        vec->z *= l;
+    }
+}
+
+
+/* Scale given vector
+ */
+static inline void dm_vector_scale(DMVector * vec, const DMFloat k)
+{
+    vec->x *= k;
+    vec->y *= k;
+    vec->z *= k;
+}
+
+
+/* Returns cross-product of two given vectors
+ */
+static inline void dm_vector_cross(DMVector *vr, const DMVector *v1, const DMVector *v2)
+{
+    vr->x = (v1->y * v2->z) - (v1->z * v2->y);
+    vr->y = (v1->z * v2->x) - (v1->x * v2->z);
+    vr->z = (v1->x * v2->y) - (v1->y * v2->x);
+}
+
+
+/* Multiply given vector with a matrix
+ */
+static inline void dm_vector_mul_by_mat(DMVector *vd, const DMVector *vs, const DMMatrix *mat)
+{
+    vd->x = (vs->x * mat->m[0][0]) + (vs->y * mat->m[1][0]) + (vs->z * mat->m[2][0]);
+    vd->y = (vs->x * mat->m[0][1]) + (vs->y * mat->m[1][1]) + (vs->z * mat->m[2][1]);
+    vd->z = (vs->x * mat->m[0][2]) + (vs->y * mat->m[1][2]) + (vs->z * mat->m[2][2]);
+}
+
+
+/* Make rotation matrix from given angles (radians)
+ */
+static inline void dm_matrix_rot_a(DMMatrix *mat, const DMFloat ax, const DMFloat ay, const DMFloat az)
+{
+    dm_matrix_rot(mat, sin(ax), sin(ay), sin(az), cos(ax), cos(ay), cos(az));
+}
 
 
 #ifdef __cplusplus
--- a/vecmattest.c	Tue Oct 09 06:06:08 2012 +0300
+++ b/vecmattest.c	Tue Oct 09 12:59:09 2012 +0300
@@ -64,7 +64,7 @@
 
 int main(int argc, char *argv[])
 {
-    DMVector a = { -5, 1, 17 }, b = { 1, 2, 0.5 };
+    DMVector a = { -5, 1, 17, 0 }, b = { 1, 2, 0.5, 0 };
     DMMatrix m;
 
     (void) argc;