[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