[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12085] branches/cloth/blender/source/ blender: arround 50% speedup in calculating spring force using OpenMP

Daniel Genrich daniel.genrich at gmx.net
Tue Sep 18 16:05:36 CEST 2007


Revision: 12085
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12085
Author:   genscher
Date:     2007-09-18 16:05:36 +0200 (Tue, 18 Sep 2007)

Log Message:
-----------
arround 50% speedup in calculating spring force using OpenMP

Modified Paths:
--------------
    branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h
    branches/cloth/blender/source/blender/blenkernel/intern/cloth.c
    branches/cloth/blender/source/blender/blenkernel/intern/implicit.c
    branches/cloth/blender/source/blender/makesdna/DNA_cloth_types.h

Modified: branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h
===================================================================
--- branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h	2007-09-18 14:01:33 UTC (rev 12084)
+++ branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h	2007-09-18 14:05:36 UTC (rev 12085)
@@ -52,7 +52,9 @@
 	#define DO_INLINE
 #endif
 
+#define CLOTH_MAX_THREAD 2
 
+
 /* goal defines */
 #define SOFTGOALSNAP  0.999f 
 
@@ -103,6 +105,7 @@
 typedef enum 
 {
 	CSPRING_FLAG_DEACTIVATE = (1 << 1),
+	CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied
 } CSPRINGS_FLAGS;
 
 // needed for buttons_object.c

Modified: branches/cloth/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- branches/cloth/blender/source/blender/blenkernel/intern/cloth.c	2007-09-18 14:01:33 UTC (rev 12084)
+++ branches/cloth/blender/source/blender/blenkernel/intern/cloth.c	2007-09-18 14:05:36 UTC (rev 12085)
@@ -117,10 +117,6 @@
 	// { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
 };
 
-#define DEBUG_CLOTH_VERBOSE	1000
-static int	DEBUG_CLOTH = 0;
-
-
 /* ********** cloth engine ******* */
 /* Prototypes for internal functions.
 */
@@ -774,7 +770,7 @@
 					solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0);
 
 				tend();
-				printf("Cloth simulation time: %f\n", (float)tval());
+				// printf("Cloth simulation time: %f\n", (float)tval());
 
 				cloth_cache_set_frame(clmd, framenr);
 

Modified: branches/cloth/blender/source/blender/blenkernel/intern/implicit.c
===================================================================
--- branches/cloth/blender/source/blender/blenkernel/intern/implicit.c	2007-09-18 14:01:33 UTC (rev 12084)
+++ branches/cloth/blender/source/blender/blenkernel/intern/implicit.c	2007-09-18 14:05:36 UTC (rev 12085)
@@ -570,7 +570,7 @@
 /* STATUS: verified */
 DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3])
 {
-	unsigned int i = 0,j=0;
+	unsigned int i = 0;
 	zero_lfvector(to, from[0].vcount);
 	/* process diagonal elements */	
 	for(i = 0; i < from[0].vcount; i++)
@@ -579,7 +579,8 @@
 	}
 
 	/* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */
-#pragma parallel for shared(to,from, fLongVector) private(i) 
+	// TODO: pragma below is wrong, correct it!
+	// #pragma omp parallel for shared(to,from, fLongVector) private(i) 
 	for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
 	{
 		// muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
@@ -804,11 +805,13 @@
 
 	return 1;
 }
+
 DO_INLINE float fb(float length, float L)
 {
 	float x = length/L;
 	return (-11.541f*pow(x,4)+34.193f*pow(x,3)-39.083f*pow(x,2)+23.116f*x-9.713f);
 }
+
 DO_INLINE float fbderiv(float length, float L)
 {
 	float x = length/L;
@@ -827,6 +830,7 @@
 	else
 		return tempfb;		
 }
+
 DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
 {
 	float tempfb = kb * fb(length, L);
@@ -841,6 +845,7 @@
 		return kb * fbderiv(length, L);	
 	}	
 }
+
 DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
 {
 	unsigned int i=0;
@@ -850,6 +855,7 @@
 		mul_fvector_fmatrix(V[S[i].r], V[S[i].r], S[i].m);
 	}
 }
+
 // block diagonalizer
 void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *S, fmatrix3x3 *bigI)
 {
@@ -874,6 +880,7 @@
 	}		
 
 }
+
 int  cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
 {
 	// Solves for unknown X in equation AX=B
@@ -1101,17 +1108,20 @@
 	mul_fmatrix_S(temp, k);
 	add_fmatrix_fmatrix(to, temp, to);
 }
+
 DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3],float length,float L,float k, float cb)
 {
 	// return  outerprod(dir,dir)*fbstar_jacobi(length, L, k, cb);
 	mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb));
 }
+
 DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping)
 {
 	// derivative of force wrt velocity.  
 	// return outerprod(dir,dir) * damping;
 	mul_fvectorT_fvectorS(to, dir, dir, damping);
 }
+
 DO_INLINE void dfdx_spring(float to[3][3],  float dir[3],float length,float L,float k)
 {
 	// dir is unit length direction, rest is spring's restlength, k is spring constant.
@@ -1122,6 +1132,7 @@
 	sub_fmatrix_fmatrix(to, to, I);
 	mul_fmatrix_S(to, -k);
 }
+
 DO_INLINE void dfdx_damp(float to[3][3],  float dir[3],float length,const float vel[3],float rest,float damping)
 {
 	// inner spring damping   vel is the relative velocity  of the endpoints.  
@@ -1132,7 +1143,7 @@
 
 }
 
-DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
+DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
 {
 	float extent[3];
 	float length = 0;
@@ -1142,25 +1153,28 @@
 	float L = s->restlen;
 	float cb = clmd->sim_parms.structural;
 
-	float f[3] = {0,0,0};
+	float nullf[3] = {0,0,0};
 	float stretch_force[3] = {0,0,0};
 	float bending_force[3] = {0,0,0};
 	float damping_force[3] = {0,0,0};
-	float dfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
-	float dfdv[3][3];
-	int needed = 0;
+	float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
 	Cloth *cloth = clmd->clothObject;
 	ClothVertex *verts = cloth->verts;
+	
+	VECCOPY(s->f, nullf);
+	cp_fmatrix(s->dfdx, nulldfdx);
+	cp_fmatrix(s->dfdv, nulldfdx);
 
 	// calculate elonglation
 	VECSUB(extent, X[s->kl], X[s->ij]);
 	VECSUB(vel, V[s->kl], V[s->ij]);
 	length = sqrt(INPR(extent, extent));
 	
+	s->flags &= ~CSPRING_FLAG_NEEDED;
 	
-	
 	if(length > ABS(ALMOST_ZERO))
 	{
+		/*
 		if(length>L)
 		{
 			if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) 
@@ -1170,7 +1184,7 @@
 				return;
 			}
 		} 
-		
+		*/
 		mul_fvector_S(dir, extent, 1.0f/length);
 	}
 	else	
@@ -1184,55 +1198,37 @@
 	{
 		if(length > L) // only on elonglation
 		{
-			needed++;
+			s->flags |= CSPRING_FLAG_NEEDED;
 
 			k = clmd->sim_parms.structural;	
 
 			mul_fvector_S(stretch_force, dir, (k*(length-L))); 
 
-			VECADD(f, f, stretch_force);
+			VECADD(s->f, s->f, stretch_force);
 
 			// Ascher & Boxman, p.21: Damping only during elonglation
 			mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); 
-			VECADD(f, f, damping_force);
+			VECADD(s->f, s->f, damping_force);
 
-			dfdx_spring_type1(dfdx, dir,length,L,k);
+			dfdx_spring_type1(s->dfdx, dir,length,L,k);
 
-			dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis);	
-				
-			sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, dfdv);
-			
-			sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, dfdv);
-
-			add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, dfdv);	
-			
+			dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis);
 		}
 	}
 	else // calculate force of bending springs
 	{
 		if(length < L)
 		{
-			k = clmd->sim_parms.bending;
+			s->flags |= CSPRING_FLAG_NEEDED;
+			
+			k = clmd->sim_parms.bending;	
 
-			needed++;	
-
 			mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
-			VECADD(f, f, bending_force);
+			VECADD(s->f, s->f, bending_force);
 
-			dfdx_spring_type2(dfdx, dir,length,L,k, cb);
+			dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
 		}
 	}
-
-	if(needed)
-	{
-		VECADD(lF[s->ij], lF[s->ij], f);
-		VECSUB(lF[s->kl], lF[s->kl], f);
-
-		sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, dfdx);
-		sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, dfdx);
-
-		add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, dfdx);
-	}
 }
 
 DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface)
@@ -1275,7 +1271,7 @@
 
 }
 
-void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time)
+void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time)
 {
 	/* Collect forces and derivatives:  F,dFdX,dFdV */
 	Cloth 		*cloth 		= clmd->clothObject;
@@ -1332,9 +1328,10 @@
 	/* handle external forces like wind */
 	if(effectors)
 	{
-		float wind[3] = {0,1.0f,0};
+		float wind[3] = {0.0f,1.0f,0.0f};
 		float force[3]= {0.0f, 0.0f, 0.0f};
-
+		
+		#pragma omp parallel for private (i) shared(lF)
 		for(i = 0; i < cloth->numverts; i++)
 		{
 			float vertexnormal[3]={0,0,0};
@@ -1348,17 +1345,55 @@
 			VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(i, wind, vertexnormal));
 		}
 	}
-
+	
 	/* calculate and apply spring forces */
+#pragma omp parallel private(i)
+	{
+#pragma omp for nowait
+	for(i = 0; i < cloth->numsprings/2; i++)
+	{
+		// only handle active springs
+		// if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
+		// {
+			cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX);
+		// }
+	}
+#pragma omp for nowait
+	for(i = cloth->numsprings/2; i < cloth->numsprings; i++)
+	{
+		// only handle active springs
+		// if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
+		// {
+		cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX);
+		// }
+	}
+#pragma omp for nowait
 	for(i = 0; i < cloth->numsprings; i++)
 	{
 		// only handle active springs
-		if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
+		// if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
 		{
-			calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX);
+			ClothSpring *s = &springs[i];
+			if(s->flags & CSPRING_FLAG_NEEDED)
+			{
+				if(s->type != BENDING)
+				{
+					sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
+					sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
+					add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv);	
+				}
+		
+				VECADD(lF[s->ij], lF[s->ij], s->f);
+				VECSUB(lF[s->kl], lF[s->kl], s->f);
+		
+				sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list