[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43080] branches/tile/source/blender/ compositor: Tile branch

Jeroen Bakker j.bakker at atmind.nl
Mon Jan 2 17:24:31 CET 2012


Revision: 43080
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43080
Author:   jbakker
Date:     2012-01-02 16:24:30 +0000 (Mon, 02 Jan 2012)
Log Message:
-----------
Tile branch

implemented the thread queue pattern for work scheduling.
This is stable and has the possibility to do OpenCL threading in the future.
This threading model is selected to be the default one.

Still needed to be tested by other users to make sure it is the right direction.

Jeroen Bakker
 - At Mind - 

Modified Paths:
--------------
    branches/tile/source/blender/compositor/COM_defines.h
    branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp
    branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h

Modified: branches/tile/source/blender/compositor/COM_defines.h
===================================================================
--- branches/tile/source/blender/compositor/COM_defines.h	2012-01-02 16:20:18 UTC (rev 43079)
+++ branches/tile/source/blender/compositor/COM_defines.h	2012-01-02 16:24:30 UTC (rev 43080)
@@ -76,11 +76,16 @@
 #define COM_TM_WORKER 3
 
 /**
+  * COM_TM_QUEUE is a multithreaded model, which uses the BLI_thread_queue pattern. it has the same speed as PTHREAD. Currently this needs to 
+  * be expended with OpenCL. After that it might become the default threading model.
+  */
+#define COM_TM_QUEUE 4
+
+/**
   * COM_CURRENT_THREADING_MODEL can be one of the above, COM_PTHREAD is currently default.
   */
-#define COM_CURRENT_THREADING_MODEL COM_TM_WORKER
+#define COM_CURRENT_THREADING_MODEL COM_TM_QUEUE
 
-
 // chunk order
 /**
   * @brief The order of chunks to be scheduled

Modified: branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp
===================================================================
--- branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp	2012-01-02 16:20:18 UTC (rev 43079)
+++ branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp	2012-01-02 16:24:30 UTC (rev 43080)
@@ -33,6 +33,7 @@
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
+#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
 #else
 #error WorkScheduler: No threading model configured
 #endif
@@ -64,6 +65,12 @@
 ThreadedWorker *cpuworker;
 #endif
 
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+/// @brief list of all thread for every CPUDevice in cpudevices a thread exists
+static ListBase cputhreads;
+static ThreadQueue * cpuqueue;
+#endif
+
 #if COM_OPENCL_ENABLED
 static cl_context context;
 static cl_program program;
@@ -78,6 +85,28 @@
 	return NULL;
 }
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+void* WorkScheduler::thread_execute_cpu(void* data) {
+	bool continueLoop = true;
+	Device* device = (Device*)data;
+	while (continueLoop) {
+		WorkPackage* work = (WorkPackage*)BLI_thread_queue_pop(cpuqueue);
+		if (work) {
+		   device->execute(work);
+		   delete work;
+		}
+		PIL_sleep_ms(10);
+
+		if (WorkScheduler::isStopping()) {
+			continueLoop = false;
+		}
+	}
+	return NULL;
+}
+
+bool WorkScheduler::isStopping() {return state == COM_WSS_STOPPING;}
+
+#endif
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
 void* WorkScheduler::thread_execute_cpu(void* data) {
 	bool continueLoop = true;
@@ -88,6 +117,7 @@
 		   device->execute(work);
 		   delete work;
 		}
+		PIL_sleep_ms(100);
 
 		if (WorkScheduler::isStopping()) {
 			continueLoop = false;
@@ -105,6 +135,7 @@
 		   device->execute(work);
 		   delete work;
 		}
+		PIL_sleep_ms(100);
 
 		if (WorkScheduler::isStopping()) {
 			continueLoop = false;
@@ -160,18 +191,22 @@
 	delete package;
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
 	BLI_insert_work(cpuworker, package);
+#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+	BLI_thread_queue_push(cpuqueue, package);
 #endif
 }
 
 void WorkScheduler::start(CompositorContext &context) {
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
 	unsigned int index;
+	cpuwork.clear();
 	BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size());
 	for (index = 0 ; index < cpudevices.size() ; index ++) {
 		Device* device = cpudevices[index];
 		BLI_insert_thread(&cputhreads, device);
 	}
 	if (context.getHasActiveOpenCLDevices()) {
+		gpuwork.clear();
 		BLI_init_threads(&gputhreads, thread_execute_gpu, gpudevices.size());
 		for (index = 0 ; index < gpudevices.size() ; index ++) {
 			Device* device = gpudevices[index];
@@ -185,18 +220,56 @@
 #if COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
 	cpuworker = BLI_create_worker(worker_execute_cpu, cpudevices.size(), 0);
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+	unsigned int index;
+	cpuqueue = BLI_thread_queue_init();
+	BLI_thread_queue_nowait(cpuqueue);
+	BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size());
+	for (index = 0 ; index < cpudevices.size() ; index ++) {
+		Device* device = cpudevices[index];
+		BLI_insert_thread(&cputhreads, device);
+	}
+#endif
+	
 	state = COM_WSS_STARTED;
 }
 
 void WorkScheduler::stop() {
 	state = COM_WSS_STOPPING;
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
+	BLI_mutex_lock(&cpumutex);
+	while (cpuwork.size()>0) {
+	   WorkPackage * result = cpuwork.front();
+	   cpuwork.pop_front();
+	   delete result;
+	}
+	BLI_mutex_unlock(&cpumutex);
 	BLI_end_threads(&cputhreads);
+
+	BLI_mutex_lock(&gpumutex);
+	while (gpuwork.size()>0) {
+	   WorkPackage * result = gpuwork.front();
+	   gpuwork.pop_front();
+	   delete result;
+	}
+	BLI_mutex_unlock(&gpumutex);
 	BLI_end_threads(&gputhreads);
 #endif
 #if COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
 	BLI_destroy_worker(cpuworker);
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+	BLI_mutex_lock(&cpumutex);
+	while (cpuwork.size()>0) {
+	   WorkPackage * result = cpuwork.front();
+	   cpuwork.pop_front();
+	   delete result;
+	}
+	BLI_mutex_unlock(&cpumutex);
+	BLI_end_threads(&cputhreads);
+	
+	BLI_thread_queue_free(cpuqueue);
+#endif
 	state = COM_WSS_STOPPED;
 }
 
@@ -235,8 +308,15 @@
 		device->initialize();
 		cpudevices.push_back(device);
 	}
+#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+	int numberOfCPUThreads = BLI_system_thread_count();
+
+	for (int index = 0 ; index < numberOfCPUThreads ; index ++) {
+		CPUDevice *device = new CPUDevice();
+		device->initialize();
+		cpudevices.push_back(device);
+	}
 #endif
-
 #if COM_OPENCL_ENABLED
 	context = NULL;
 	program = NULL;

Modified: branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h
===================================================================
--- branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h	2012-01-02 16:20:18 UTC (rev 43079)
+++ branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h	2012-01-02 16:24:30 UTC (rev 43080)
@@ -68,7 +68,18 @@
 	  */
 	static void* thread_execute_gpu(void* data);
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+	/**
+	  * @brief are we being stopped.
+	  */
+	static bool isStopping();
 
+	/**
+	  * @brief main thread loop for cpudevices
+	  * inside this loop new work is queried and being executed
+	  */
+	static void* thread_execute_cpu(void* data);
+#endif	
 public:
 	/**
 	  * @brief schedule a chunk of a group to be calculated.



More information about the Bf-blender-cvs mailing list