new implementation of sample_queue pyrit
authorRadek Brich <radek.brich@devl.cz>
Fri, 28 Mar 2008 23:30:04 +0100
branchpyrit
changeset 52 a6413a3d741d
parent 51 89fec8668768
child 53 228cb8bfdd54
new implementation of sample_queue
include/common.h
include/raytracer.h
src/raytracer.cc
--- a/include/common.h	Fri Mar 28 21:47:32 2008 +0100
+++ b/include/common.h	Fri Mar 28 23:30:04 2008 +0100
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <float.h>
+#include <pthread.h>
 
 #ifdef PYRIT_DOUBLE
 # define Float double
@@ -46,20 +47,27 @@
 1: major status messages (*)
 2: minor status, progress (-)
 3: debug messages (D)
-4: more debug
+4: thread debug
 default = 2
 */
 extern int pyrit_verbosity;
 
 inline void dbgmsg(const int vlevel, const char *format, ...)
 {
+	static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 	if (pyrit_verbosity >= vlevel)
 	{
+		if (pyrit_verbosity >= 4)
+			pthread_mutex_lock(&mutex);
+
 		va_list ap;
 		va_start(ap, format);
 		vprintf(format, ap);
 		va_end(ap);
 		fflush(stdout);
+
+		if (pyrit_verbosity >= 4)
+			pthread_mutex_unlock(&mutex);
 	}
 }
 
--- a/include/raytracer.h	Fri Mar 28 21:47:32 2008 +0100
+++ b/include/raytracer.h	Fri Mar 28 23:30:04 2008 +0100
@@ -61,8 +61,9 @@
 	int max_depth;
 
 	Vector3 SphereDistribute(int i, int n, Float extent, Vector3 &normal);
-	
-	queue<Sample*> sample_queue;
+
+	Sample **sample_queue;
+	int sample_queue_max, sample_queue_pos, sample_queue_count;
 	bool sample_queue_end;
 	pthread_mutex_t sample_queue_mutex, sampler_mutex;
 	pthread_cond_t sample_queue_cond, worker_ready_cond;
--- a/src/raytracer.cc	Fri Mar 28 21:47:32 2008 +0100
+++ b/src/raytracer.cc	Fri Mar 28 23:30:04 2008 +0100
@@ -24,15 +24,12 @@
  * THE SOFTWARE.
  */
 
-#ifdef PTHREADS
 #include <pthread.h>
-#endif
-
 #include <stdio.h>
 #include <malloc.h>
 #include "raytracer.h"
 
-int pyrit_verbosity = 2;
+int pyrit_verbosity = 4;
 
 // Hammersley spherical point distribution
 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
@@ -407,17 +404,21 @@
 		pthread_mutex_lock(&rt->sample_queue_mutex);
 		pthread_cond_signal(&rt->worker_ready_cond);
 
-		while (rt->sample_queue.empty()) {
+		while (rt->sample_queue_count == 0)
+		{
 			if (rt->sample_queue_end)
 			{
+				dbgmsg(4, "T thread [%d] exiting\n", pthread_self());
 				pthread_mutex_unlock(&rt->sample_queue_mutex);
 				pthread_exit(NULL);
 			}
 			pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
 		}
 
-		sample = rt->sample_queue.front();
-		rt->sample_queue.pop();
+		sample = rt->sample_queue[rt->sample_queue_pos++];
+		rt->sample_queue_count--;
+		if (rt->sample_queue_pos > rt->sample_queue_max)
+			rt->sample_queue_pos = 0;
 
 		pthread_mutex_unlock(&rt->sample_queue_mutex);
 
@@ -443,6 +444,10 @@
 		return;
 
 	sample_queue_end = false;
+	sample_queue_max = 2000;
+	sample_queue = new Sample* [sample_queue_max+1];
+	sample_queue_pos = 0;
+	sample_queue_count = 0;
 
 	// create workers
 	dbgmsg(1, "* running %d threads\n", num_threads);
@@ -460,32 +465,42 @@
 	dbgmsg(2, "-  0%% done");
 
 	sampler->init();
+	Sample *sample;
 	int sampnum = 0, sampdone;
-	Sample *sample;
+	int my_pos = 0, my_count;
 
 	pthread_mutex_lock(&sampler_mutex);
 	while ( (sampnum = sampler->initSampleSet()) > 0 )
 	{
 		sampdone = 0;
-		while ( (sample = sampler->nextSample()) != NULL )
+		for (;;)
 		{
+			my_count = 0;
+			while ( (sample = sampler->nextSample()) != NULL )
+			{
+				sample_queue[my_pos++] = sample;
+				my_count++;
+				if (my_count >= 1000)
+					break;
+				if (my_pos > sample_queue_max)
+					my_pos = 0;
+			}
+			if (sample == NULL)
+				break;
+
 			pthread_mutex_unlock(&sampler_mutex);
 			pthread_mutex_lock(&sample_queue_mutex);
-			sample_queue.push(sample);
+			sample_queue_count += my_count;
 
 			// wait for workers if there is enough samples ready on queue
-			if (sample_queue.size() > 1000)
+			while (sample_queue_count > 1000)
 			{
-				while (sample_queue.size() > 100)
-				{
-					pthread_cond_signal(&sample_queue_cond);
-					pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
-				}
+				pthread_cond_signal(&sample_queue_cond);
+				pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
 			}
 
-			sampdone++;
-			if ((sampdone & 0xfff) == 0)
-				dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue.size())*100/sampnum);
+			sampdone += my_count;
+			dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue_count)*100/sampnum);
 
 			pthread_cond_signal(&sample_queue_cond);
 			pthread_mutex_unlock(&sample_queue_mutex);
@@ -500,7 +515,7 @@
 
 	pthread_mutex_lock(&sample_queue_mutex);
 	sample_queue_end = true;
-	while (!sample_queue.empty())
+	while (sample_queue_count)
 	{
 		pthread_cond_broadcast(&sample_queue_cond);
 		pthread_mutex_unlock(&sample_queue_mutex);
@@ -512,8 +527,9 @@
 	for (int t = 0; t < num_threads; t++)
 		pthread_join(threads[t], NULL);
 
+	delete[] sample_queue;
+
 #if 0
-
 	RenderrowData *d;
 
 	Float S = 0.5/w;