[Bf-blender-cvs] [4b04fad] cycles_memory_experiments: Smoke: Don't allocate arrays needed for hi-res simulation if smoke is baked to file

Sergey Sharybin noreply at git.blender.org
Wed Apr 15 17:41:37 CEST 2015


Commit: 4b04fad0a99d45d962c54ae3db8a11da79f44753
Author: Sergey Sharybin
Date:   Wed Apr 15 20:35:02 2015 +0500
Branches: cycles_memory_experiments
https://developer.blender.org/rB4b04fad0a99d45d962c54ae3db8a11da79f44753

Smoke: Don't allocate arrays needed for hi-res simulation if smoke is baked to file

There used to be quite huge 3D arrays stored in memory which are only needed for
simulation steps and not used at all if the smoke is baked to file. That memory
is unmanaged by blender and not visible in the info space header and in practice
they could easily be gigabytes for hires smoke.

This commit only addressed hires smoke since it's the more important at this
point, and non-hires smoke wouldn't have such noticeable benefit.

In the case of tornado file it gives around 20% memory saving (which is about
26GB vs. 33GB on later frames of 01.03.02.A3 shot.

===================================================================

M	intern/smoke/extern/smoke_API.h
M	intern/smoke/intern/WTURBULENCE.cpp
M	intern/smoke/intern/WTURBULENCE.h
M	intern/smoke/intern/smoke_API.cpp
M	source/blender/blenkernel/intern/smoke.c

===================================================================

diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h
index 08dbded..3c86bc9 100644
--- a/intern/smoke/extern/smoke_API.h
+++ b/intern/smoke/extern/smoke_API.h
@@ -74,7 +74,7 @@ size_t smoke_get_index2d(int x, int max_x, int y);
 void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log);
 
 // wavelet turbulence functions
-struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, const char *noisefile_path, int use_fire, int use_colors);
+struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, const char *noisefile_path, int use_fire, int use_colors, int use_sim);
 void smoke_turbulence_free(struct WTURBULENCE *wt);
 void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid);
 
diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp
index 3d712d2..40b687e 100644
--- a/intern/smoke/intern/WTURBULENCE.cpp
+++ b/intern/smoke/intern/WTURBULENCE.cpp
@@ -51,7 +51,7 @@ static const float persistence = 0.56123f;
 //////////////////////////////////////////////////////////////////////
 // constructor
 //////////////////////////////////////////////////////////////////////
-WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, const char *noisefile_path, int init_fire, int init_colors)
+WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, const char *noisefile_path, int init_fire, int init_colors, int init_sim)
 {
 	// if noise magnitude is below this threshold, its contribution
 	// is negilgible, so stop evaluating new octaves
@@ -87,11 +87,14 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no
 	// allocate high resolution density field
 	_totalStepsBig = 0;
 	_densityBig = new float[_totalCellsBig];
-	_densityBigOld = new float[_totalCellsBig];
-	
-	for(int i = 0; i < _totalCellsBig; i++) {
-		_densityBig[i] = 
-		_densityBigOld[i] = 0.;
+	memset(_densityBig, 0, sizeof(*_densityBig) * _totalCellsBig);
+
+	if (init_sim) {
+		_densityBigOld = new float[_totalCellsBig];
+		memset(_densityBigOld, 0, sizeof(*_densityBigOld) * _totalCellsBig);
+	}
+	else {
+		_densityBigOld = NULL;
 	}
 
 	/* fire */
@@ -112,7 +115,6 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no
 	_tcU = new float[_totalCellsSm];
 	_tcV = new float[_totalCellsSm];
 	_tcW = new float[_totalCellsSm];
-	_tcTemp = new float[_totalCellsSm];
 	
 	// map all 
 	const float dx = 1.0f/(float)(_resSm[0]);
@@ -126,12 +128,21 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no
 		_tcU[index] = x*dx;
 		_tcV[index] = y*dy;
 		_tcW[index] = z*dz;
-		_tcTemp[index] = 0.;
 		}
 	
+	if (init_sim) {
+		_tcTemp = new float[_totalCellsSm];
+		memset(_tcTemp, 0, sizeof(*_tcTemp) * _totalCellsSm);
+	}
+	else {
+		_tcTemp = NULL;
+	}
+
 	// noise tiles
 	_noiseTile = new float[noiseTileSize * noiseTileSize * noiseTileSize];
 	setNoise(noisetype, noisefile_path);
+
+	_need_sim_data = init_sim != 0;
 }
 
 void WTURBULENCE::initFire()
@@ -139,16 +150,15 @@ void WTURBULENCE::initFire()
 	if (!_fuelBig) {
 		_flameBig = new float[_totalCellsBig];
 		_fuelBig = new float[_totalCellsBig];
-		_fuelBigOld = new float[_totalCellsBig];
 		_reactBig = new float[_totalCellsBig];
-		_reactBigOld = new float[_totalCellsBig];
-
-		for(int i = 0; i < _totalCellsBig; i++) {
-			_flameBig[i] = 
-			_fuelBig[i] = 
-			_fuelBigOld[i] = 0.;
-			_reactBig[i] = 
-			_reactBigOld[i] = 0.;
+		memset(_flameBig, 0, sizeof(*_flameBig) * _totalCellsBig);
+		memset(_fuelBig, 0, sizeof(*_fuelBig) * _totalCellsBig);
+		memset(_reactBig, 0, sizeof(*_reactBig) * _totalCellsBig);
+		if (_need_sim_data) {
+			_fuelBigOld = new float[_totalCellsBig];
+			_reactBigOld = new float[_totalCellsBig];
+			memset(_fuelBigOld, 0, sizeof(*_fuelBigOld) * _totalCellsBig);
+			memset(_reactBigOld, 0, sizeof(*_reactBigOld) * _totalCellsBig);
 		}
 	}
 }
@@ -157,19 +167,20 @@ void WTURBULENCE::initColors(float init_r, float init_g, float init_b)
 {
 	if (!_color_rBig) {
 		_color_rBig = new float[_totalCellsBig];
-		_color_rBigOld = new float[_totalCellsBig];
 		_color_gBig = new float[_totalCellsBig];
-		_color_gBigOld = new float[_totalCellsBig];
 		_color_bBig = new float[_totalCellsBig];
-		_color_bBigOld = new float[_totalCellsBig];
-
 		for(int i = 0; i < _totalCellsBig; i++) {
 			_color_rBig[i] = _densityBig[i] * init_r;
-			_color_rBigOld[i] = 0.0f;
 			_color_gBig[i] = _densityBig[i] * init_g;
-			_color_gBigOld[i] = 0.0f;
 			_color_bBig[i] = _densityBig[i] * init_b;
-			_color_bBigOld[i] = 0.0f;
+		}
+		if (_need_sim_data) {
+			_color_rBigOld = new float[_totalCellsBig];
+			_color_gBigOld = new float[_totalCellsBig];
+			_color_bBigOld = new float[_totalCellsBig];
+			memset(_color_rBigOld, 0, sizeof(*_color_rBigOld) * _totalCellsBig);
+			memset(_color_gBigOld, 0, sizeof(*_color_gBigOld) * _totalCellsBig);
+			memset(_color_bBigOld, 0, sizeof(*_color_bBigOld) * _totalCellsBig);
 		}
 	}
 }
@@ -179,7 +190,7 @@ void WTURBULENCE::initColors(float init_r, float init_g, float init_b)
 //////////////////////////////////////////////////////////////////////
 WTURBULENCE::~WTURBULENCE() {
   delete[] _densityBig;
-  delete[] _densityBigOld;
+  if (_densityBigOld) delete[] _densityBigOld;
   if (_flameBig) delete[] _flameBig;
   if (_fuelBig) delete[] _fuelBig;
   if (_fuelBigOld) delete[] _fuelBigOld;
@@ -196,7 +207,7 @@ WTURBULENCE::~WTURBULENCE() {
   delete[] _tcU;
   delete[] _tcV;
   delete[] _tcW;
-  delete[] _tcTemp;
+  if (_tcTemp) delete[] _tcTemp;
 
   delete[] _noiseTile;
 }
diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h
index 3663532..206a278 100644
--- a/intern/smoke/intern/WTURBULENCE.h
+++ b/intern/smoke/intern/WTURBULENCE.h
@@ -36,7 +36,7 @@ struct WTURBULENCE
 {
 	public:
 		// both config files can be NULL, altCfg might override values from noiseCfg
-		WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, const char *noisefile_path, int init_fire, int init_colors);
+		WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, const char *noisefile_path, int init_fire, int init_colors, int init_sim);
 
 		/// destructor
 		virtual ~WTURBULENCE();
@@ -144,6 +144,8 @@ struct WTURBULENCE
 		
 		void computeEigenvalues(float *_eigMin, float *_eigMax);
 		void decomposeEnergy(float *energy, float *_highFreqEnergy);
+
+		bool _need_sim_data;
 };
 
 #endif // WTURBULENCE_H
diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp
index d79aaf7..829ece8 100644
--- a/intern/smoke/intern/smoke_API.cpp
+++ b/intern/smoke/intern/smoke_API.cpp
@@ -44,10 +44,10 @@ extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, i
 	return fluid;
 }
 
-extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, const char *noisefile_path, int use_fire, int use_colors)
+extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, const char *noisefile_path, int use_fire, int use_colors, int use_sim)
 {
 	if (amplify)
-		return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, noisefile_path, use_fire, use_colors);
+		return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, noisefile_path, use_fire, use_colors, use_sim);
 	else 
 		return NULL;
 }
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 770ef4c..3152cdb 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -196,6 +196,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
 {
 	int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE));
 	int use_colors = (sds->active_fields & SM_ACTIVE_COLORS);
+	int use_sim = !(sds->point_cache[0] && (sds->point_cache[0]->flag & (PTCACHE_BAKED|PTCACHE_DISK_CACHE)));
 
 	if (free_old && sds->wt)
 		smoke_turbulence_free(sds->wt);
@@ -207,7 +208,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
 	/* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */
 	BLI_lock_thread(LOCK_FFTW);
 
-	sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors);
+	sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors, use_sim);
 
 	BLI_unlock_thread(LOCK_FFTW);




More information about the Bf-blender-cvs mailing list