[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45916] branches/soc-2011-tomato/intern/ cycles: Cycles: centralized task scheduler for multithreading, which is basically the

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Apr 24 13:43:42 CEST 2012


Revision: 45916
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45916
Author:   blendix
Date:     2012-04-24 11:43:41 +0000 (Tue, 24 Apr 2012)
Log Message:
-----------
Cycles: centralized task scheduler for multithreading, which is basically the
CPU device threading code wrapped into something reusable.
		    
Basic idea is that there is a single TaskScheduler that keeps a pool of threads,
one for each core. Other places in the code can then create a TaskPool that they
can drop Tasks in to be executed by the scheduler, and wait for them to complete
or cancel them early.

Modified Paths:
--------------
    branches/soc-2011-tomato/intern/cycles/device/device.cpp
    branches/soc-2011-tomato/intern/cycles/device/device.h
    branches/soc-2011-tomato/intern/cycles/device/device_cpu.cpp
    branches/soc-2011-tomato/intern/cycles/device/device_multi.cpp
    branches/soc-2011-tomato/intern/cycles/render/session.cpp
    branches/soc-2011-tomato/intern/cycles/util/CMakeLists.txt
    branches/soc-2011-tomato/intern/cycles/util/util_math.h
    branches/soc-2011-tomato/intern/cycles/util/util_thread.h
    branches/soc-2011-tomato/intern/cycles/util/util_types.h

Added Paths:
-----------
    branches/soc-2011-tomato/intern/cycles/util/util_task.cpp
    branches/soc-2011-tomato/intern/cycles/util/util_task.h

Modified: branches/soc-2011-tomato/intern/cycles/device/device.cpp
===================================================================
--- branches/soc-2011-tomato/intern/cycles/device/device.cpp	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/device/device.cpp	2012-04-24 11:43:41 UTC (rev 45916)
@@ -58,15 +58,6 @@
 	split(tasks, num);
 }
 
-void DeviceTask::split(ThreadQueue<DeviceTask>& queue, int num)
-{
-	list<DeviceTask> tasks;
-	split(tasks, num);
-
-	foreach(DeviceTask& task, tasks)
-		queue.push(task);
-}
-
 void DeviceTask::split(list<DeviceTask>& tasks, int num)
 {
 	if(type == SHADER) {

Modified: branches/soc-2011-tomato/intern/cycles/device/device.h
===================================================================
--- branches/soc-2011-tomato/intern/cycles/device/device.h	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/device/device.h	2012-04-24 11:43:41 UTC (rev 45916)
@@ -25,6 +25,7 @@
 
 #include "util_list.h"
 #include "util_string.h"
+#include "util_task.h"
 #include "util_thread.h"
 #include "util_types.h"
 #include "util_vector.h"
@@ -66,7 +67,7 @@
 
 /* Device Task */
 
-class DeviceTask {
+class DeviceTask : public Task {
 public:
 	typedef enum { PATH_TRACE, TONEMAP, SHADER } Type;
 	Type type;
@@ -87,7 +88,6 @@
 	DeviceTask(Type type = PATH_TRACE);
 
 	void split(list<DeviceTask>& tasks, int num);
-	void split(ThreadQueue<DeviceTask>& tasks, int num);
 	void split_max_size(list<DeviceTask>& tasks, int max_size);
 };
 

Modified: branches/soc-2011-tomato/intern/cycles/device/device_cpu.cpp
===================================================================
--- branches/soc-2011-tomato/intern/cycles/device/device_cpu.cpp	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/device/device_cpu.cpp	2012-04-24 11:43:41 UTC (rev 45916)
@@ -40,35 +40,21 @@
 class CPUDevice : public Device
 {
 public:
-	vector<thread*> threads;
-	ThreadQueue<DeviceTask> tasks;
+	TaskPool task_pool;
 	KernelGlobals *kg;
 	
 	CPUDevice(int threads_num)
+	: task_pool(function_bind(&CPUDevice::thread_run, this, _1, _2))
 	{
 		kg = kernel_globals_create();
 
 		/* do now to avoid thread issues */
 		system_cpu_support_optimized();
-
-		if(threads_num == 0)
-			threads_num = system_cpu_thread_count();
-
-		threads.resize(threads_num);
-
-		for(size_t i = 0; i < threads.size(); i++)
-			threads[i] = new thread(function_bind(&CPUDevice::thread_run, this, i));
 	}
 
 	~CPUDevice()
 	{
-		tasks.stop();
-
-		foreach(thread *t, threads) {
-			t->join();
-			delete t;
-		}
-
+		task_pool.stop();
 		kernel_globals_free(kg);
 	}
 
@@ -127,25 +113,21 @@
 #endif
 	}
 
-	void thread_run(int t)
+	void thread_run(Task *task_, int thread_id)
 	{
-		DeviceTask task;
+		DeviceTask *task = (DeviceTask*)task_;
 
-		while(tasks.worker_wait_pop(task)) {
-			if(task.type == DeviceTask::PATH_TRACE)
-				thread_path_trace(task);
-			else if(task.type == DeviceTask::TONEMAP)
-				thread_tonemap(task);
-			else if(task.type == DeviceTask::SHADER)
-				thread_shader(task);
-
-			tasks.worker_done();
-		}
+		if(task->type == DeviceTask::PATH_TRACE)
+			thread_path_trace(*task);
+		else if(task->type == DeviceTask::TONEMAP)
+			thread_tonemap(*task);
+		else if(task->type == DeviceTask::SHADER)
+			thread_shader(*task);
 	}
 
 	void thread_path_trace(DeviceTask& task)
 	{
-		if(tasks.worker_cancel())
+		if(task_pool.cancelled())
 			return;
 
 #ifdef WITH_OSL
@@ -160,7 +142,7 @@
 					kernel_cpu_optimized_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state,
 						task.sample, x, y, task.offset, task.stride);
 
-				if(tasks.worker_cancel())
+				if(task_pool.cancelled())
 					break;
 			}
 		}
@@ -172,7 +154,7 @@
 					kernel_cpu_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state,
 						task.sample, x, y, task.offset, task.stride);
 
-				if(tasks.worker_cancel())
+				if(task_pool.cancelled())
 					break;
 			}
 		}
@@ -214,7 +196,7 @@
 			for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
 				kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
 
-				if(tasks.worker_cancel())
+				if(task_pool.cancelled())
 					break;
 			}
 		}
@@ -224,7 +206,7 @@
 			for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
 				kernel_cpu_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
 
-				if(tasks.worker_cancel())
+				if(task_pool.cancelled())
 					break;
 			}
 		}
@@ -239,17 +221,22 @@
 	{
 		/* split task into smaller ones, more than number of threads for uneven
 		   workloads where some parts of the image render slower than others */
-		task.split(tasks, threads.size()*10);
+		list<DeviceTask> tasks;
+
+		task.split(tasks, TaskScheduler::num_threads()*10);
+
+		foreach(DeviceTask& task, tasks)
+			task_pool.push(new DeviceTask(task));
 	}
 
 	void task_wait()
 	{
-		tasks.wait_done();
+		task_pool.wait();
 	}
 
 	void task_cancel()
 	{
-		tasks.cancel();
+		task_pool.cancel();
 	}
 };
 

Modified: branches/soc-2011-tomato/intern/cycles/device/device_multi.cpp
===================================================================
--- branches/soc-2011-tomato/intern/cycles/device/device_multi.cpp	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/device/device_multi.cpp	2012-04-24 11:43:41 UTC (rev 45916)
@@ -257,13 +257,14 @@
 
 	void task_add(DeviceTask& task)
 	{
-		ThreadQueue<DeviceTask> tasks;
+		list<DeviceTask> tasks;
 		task.split(tasks, devices.size());
 
 		foreach(SubDevice& sub, devices) {
-			DeviceTask subtask;
+			if(!tasks.empty()) {
+				DeviceTask subtask = tasks.front();
+				tasks.pop_front();
 
-			if(tasks.worker_wait_pop(subtask)) {
 				if(task.buffer) subtask.buffer = sub.ptr_map[task.buffer];
 				if(task.rng_state) subtask.rng_state = sub.ptr_map[task.rng_state];
 				if(task.rgba) subtask.rgba = sub.ptr_map[task.rgba];

Modified: branches/soc-2011-tomato/intern/cycles/render/session.cpp
===================================================================
--- branches/soc-2011-tomato/intern/cycles/render/session.cpp	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/render/session.cpp	2012-04-24 11:43:41 UTC (rev 45916)
@@ -27,6 +27,7 @@
 
 #include "util_foreach.h"
 #include "util_function.h"
+#include "util_task.h"
 #include "util_time.h"
 
 CCL_NAMESPACE_BEGIN
@@ -37,6 +38,8 @@
 {
 	device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
 
+	TaskScheduler::init(params.threads);
+
 	device = Device::create(params.device, params.background, params.threads);
 	buffers = new RenderBuffers(device);
 	display = new DisplayBuffer(device);
@@ -88,6 +91,8 @@
 	delete display;
 	delete scene;
 	delete device;
+
+	TaskScheduler::exit();
 }
 
 void Session::start()

Modified: branches/soc-2011-tomato/intern/cycles/util/CMakeLists.txt
===================================================================
--- branches/soc-2011-tomato/intern/cycles/util/CMakeLists.txt	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/util/CMakeLists.txt	2012-04-24 11:43:41 UTC (rev 45916)
@@ -15,6 +15,7 @@
 	util_path.cpp
 	util_string.cpp
 	util_system.cpp
+	util_task.cpp
 	util_time.cpp
 	util_transform.cpp
 )
@@ -50,6 +51,7 @@
 	util_set.h
 	util_string.h
 	util_system.h
+	util_task.h
 	util_thread.h
 	util_time.h
 	util_transform.h

Modified: branches/soc-2011-tomato/intern/cycles/util/util_math.h
===================================================================
--- branches/soc-2011-tomato/intern/cycles/util/util_math.h	2012-04-24 10:25:12 UTC (rev 45915)
+++ branches/soc-2011-tomato/intern/cycles/util/util_math.h	2012-04-24 11:43:41 UTC (rev 45916)
@@ -578,51 +578,43 @@
 
 __device_inline float4 operator-(const float4& a)
 {
-	float4 r = {-a.x, -a.y, -a.z, -a.w};
-	return r;
+	return make_float4(-a.x, -a.y, -a.z, -a.w);
 }
 
 __device_inline float4 operator*(const float4& a, const float4& b)
 {
-	float4 r = {a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w};
-	return r;
+	return make_float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w);
 }
 
 __device_inline float4 operator*(const float4& a, float f)
 {
-	float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
-	return r;
+	return make_float4(a.x*f, a.y*f, a.z*f, a.w*f);
 }
 
 __device_inline float4 operator*(float f, const float4& a)
 {
-	float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
-	return r;
+	return make_float4(a.x*f, a.y*f, a.z*f, a.w*f);
 }
 
 __device_inline float4 operator/(const float4& a, float f)
 {
 	float invf = 1.0f/f;
-	float4 r = {a.x*invf, a.y*invf, a.z*invf, a.w*invf};
-	return r;
+	return make_float4(a.x*invf, a.y*invf, a.z*invf, a.w*invf);
 }
 
 __device_inline float4 operator/(const float4& a, const float4& b)
 {
-	float4 r = {a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w};
-	return r;
+	return make_float4(a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w);
 }
 
 __device_inline float4 operator+(const float4& a, const float4& b)
 {
-	float4 r = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w};
-	return r;
+	return make_float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
 }
 
 __device_inline float4 operator-(const float4& a, const float4& b)
 {
-	float4 r = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w};
-	return r;
+	return make_float4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w);
 }
 
 __device_inline float4 operator+=(float4& a, const float4& b)
@@ -653,6 +645,21 @@
 	return a;
 }
 
+__device_inline int4 operator<(const float4& a, const float4& b)
+{
+	return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w);
+}
+
+__device_inline int4 operator<=(const float4& a, const float4& b)
+{
+	return make_int4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w);
+}
+
+__device_inline bool operator==(const float4 a, const float4 b)
+{
+	return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
+}
+
 __device_inline float dot(const float4& a, const float4& b)
 {
 	return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
@@ -660,8 +667,7 @@
 
 __device_inline float4 cross(const float4& a, const float4& b)
 {
-	float4 r = {a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x, 0.0f};
-	return r;
+	return make_float4(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x, 0.0f);
 }
 
 __device_inline float4 min(float4 a, float4 b)
@@ -674,6 +680,31 @@
 	return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
 }
 
+__device_inline float4 select(const int4& mask, const float4& a, const float4& b)
+{
+	return make_float4((mask.x)? a.x: b.x, (mask.y)? a.y: b.y, (mask.z)? a.z: b.z, (mask.w)? a.w: b.w);
+}
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list