[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59676] trunk/blender/intern/cycles: Fix #36137: cycles render not using all GPU's when the number of GPU' s is larger
Brecht Van Lommel
brechtvanlommel at pandora.be
Sat Aug 31 01:09:23 CEST 2013
Revision: 59676
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59676
Author: blendix
Date: 2013-08-30 23:09:22 +0000 (Fri, 30 Aug 2013)
Log Message:
-----------
Fix #36137: cycles render not using all GPU's when the number of GPU's is larger
than the number of CPU threads
Modified Paths:
--------------
trunk/blender/intern/cycles/device/device_cuda.cpp
trunk/blender/intern/cycles/device/device_opencl.cpp
trunk/blender/intern/cycles/util/util_task.cpp
trunk/blender/intern/cycles/util/util_task.h
Modified: trunk/blender/intern/cycles/device/device_cuda.cpp
===================================================================
--- trunk/blender/intern/cycles/device/device_cuda.cpp 2013-08-30 22:04:37 UTC (rev 59675)
+++ trunk/blender/intern/cycles/device/device_cuda.cpp 2013-08-30 23:09:22 UTC (rev 59676)
@@ -37,7 +37,7 @@
class CUDADevice : public Device
{
public:
- TaskPool task_pool;
+ DedicatedTaskPool task_pool;
CUdevice cuDevice;
CUcontext cuContext;
CUmodule cuModule;
@@ -976,7 +976,7 @@
void task_wait()
{
- task_pool.wait_work();
+ task_pool.wait();
}
void task_cancel()
Modified: trunk/blender/intern/cycles/device/device_opencl.cpp
===================================================================
--- trunk/blender/intern/cycles/device/device_opencl.cpp 2013-08-30 22:04:37 UTC (rev 59675)
+++ trunk/blender/intern/cycles/device/device_opencl.cpp 2013-08-30 23:09:22 UTC (rev 59676)
@@ -314,7 +314,7 @@
class OpenCLDevice : public Device
{
public:
- TaskPool task_pool;
+ DedicatedTaskPool task_pool;
cl_context cxContext;
cl_command_queue cqCommandQueue;
cl_platform_id cpPlatform;
@@ -1100,7 +1100,7 @@
void task_wait()
{
- task_pool.wait_work();
+ task_pool.wait();
}
void task_cancel()
Modified: trunk/blender/intern/cycles/util/util_task.cpp
===================================================================
--- trunk/blender/intern/cycles/util/util_task.cpp 2013-08-30 22:04:37 UTC (rev 59675)
+++ trunk/blender/intern/cycles/util/util_task.cpp 2013-08-30 23:09:22 UTC (rev 59676)
@@ -168,7 +168,7 @@
thread_mutex TaskScheduler::mutex;
int TaskScheduler::users = 0;
vector<thread*> TaskScheduler::threads;
-volatile bool TaskScheduler::do_exit = false;
+bool TaskScheduler::do_exit = false;
list<TaskScheduler::Entry> TaskScheduler::queue;
thread_mutex TaskScheduler::queue_mutex;
@@ -298,5 +298,153 @@
pool->num_decrease(done);
}
+/* Dedicated Task Pool */
+
+DedicatedTaskPool::DedicatedTaskPool()
+{
+ do_cancel = false;
+ do_exit = false;
+ num = 0;
+
+ worker_thread = new thread(function_bind(&DedicatedTaskPool::thread_run, this));
+}
+
+DedicatedTaskPool::~DedicatedTaskPool()
+{
+ stop();
+ worker_thread->join();
+ delete worker_thread;
+}
+
+void DedicatedTaskPool::push(Task *task, bool front)
+{
+ num_increase();
+
+ /* add task to queue */
+ queue_mutex.lock();
+ if(front)
+ queue.push_front(task);
+ else
+ queue.push_back(task);
+
+ queue_cond.notify_one();
+ queue_mutex.unlock();
+}
+
+void DedicatedTaskPool::push(const TaskRunFunction& run, bool front)
+{
+ push(new Task(run), front);
+}
+
+void DedicatedTaskPool::wait()
+{
+ thread_scoped_lock num_lock(num_mutex);
+
+ while(num)
+ num_cond.wait(num_lock);
+}
+
+void DedicatedTaskPool::cancel()
+{
+ do_cancel = true;
+
+ clear();
+ wait();
+
+ do_cancel = false;
+}
+
+void DedicatedTaskPool::stop()
+{
+ clear();
+
+ do_exit = true;
+ queue_cond.notify_all();
+
+ wait();
+
+ assert(num == 0);
+}
+
+bool DedicatedTaskPool::cancelled()
+{
+ return do_cancel;
+}
+
+void DedicatedTaskPool::num_decrease(int done)
+{
+ num_mutex.lock();
+ num -= done;
+
+ assert(num >= 0);
+ if(num == 0)
+ num_cond.notify_all();
+
+ num_mutex.unlock();
+}
+
+void DedicatedTaskPool::num_increase()
+{
+ thread_scoped_lock num_lock(num_mutex);
+ num++;
+ num_cond.notify_all();
+}
+
+bool DedicatedTaskPool::thread_wait_pop(Task*& task)
+{
+ thread_scoped_lock queue_lock(queue_mutex);
+
+ while(queue.empty() && !do_exit)
+ queue_cond.wait(queue_lock);
+
+ if(queue.empty()) {
+ assert(do_exit);
+ return false;
+ }
+
+ task = queue.front();
+ queue.pop_front();
+
+ return true;
+}
+
+void DedicatedTaskPool::thread_run()
+{
+ Task *task;
+
+ /* keep popping off tasks */
+ while(thread_wait_pop(task)) {
+ /* run task */
+ task->run();
+
+ /* delete task */
+ delete task;
+
+ /* notify task was done */
+ num_decrease(1);
+ }
+}
+
+void DedicatedTaskPool::clear()
+{
+ thread_scoped_lock queue_lock(queue_mutex);
+
+ /* erase all tasks from the queue */
+ list<Task*>::iterator it = queue.begin();
+ int done = 0;
+
+ while(it != queue.end()) {
+ done++;
+ delete *it;
+
+ it = queue.erase(it);
+ }
+
+ queue_lock.unlock();
+
+ /* notify done */
+ num_decrease(done);
+}
+
CCL_NAMESPACE_END
Modified: trunk/blender/intern/cycles/util/util_task.h
===================================================================
--- trunk/blender/intern/cycles/util/util_task.h 2013-08-30 22:04:37 UTC (rev 59675)
+++ trunk/blender/intern/cycles/util/util_task.h 2013-08-30 23:09:22 UTC (rev 59676)
@@ -50,7 +50,7 @@
* pool, we can wait for all tasks to be done, or cancel them before they are
* done.
*
- * The run callback that actually executes the task may be create like this:
+ * The run callback that actually executes the task may be created like this:
* function_bind(&MyClass::task_execute, this, _1, _2) */
class TaskPool
@@ -77,8 +77,8 @@
thread_mutex num_mutex;
thread_condition_variable num_cond;
- volatile int num;
- volatile bool do_cancel;
+ int num;
+ bool do_cancel;
};
/* Task Scheduler
@@ -109,7 +109,7 @@
static thread_mutex mutex;
static int users;
static vector<thread*> threads;
- static volatile bool do_exit;
+ static bool do_exit;
static list<Entry> queue;
static thread_mutex queue_mutex;
@@ -122,6 +122,51 @@
static void clear(TaskPool *pool);
};
+/* Dedicated Task Pool
+ *
+ * Like a TaskPool, but will launch one dedicated thread to execute all tasks.
+ *
+ * The run callback that actually executes the task may be created like this:
+ * function_bind(&MyClass::task_execute, this, _1, _2) */
+
+class DedicatedTaskPool
+{
+public:
+ DedicatedTaskPool();
+ ~DedicatedTaskPool();
+
+ void push(Task *task, bool front = false);
+ void push(const TaskRunFunction& run, bool front = false);
+
+ void wait(); /* wait until all tasks are done */
+ void cancel(); /* cancel all tasks, keep worker thread running */
+ void stop(); /* stop worker thread */
+
+ bool cancelled(); /* for worker thread, test if cancelled */
+
+protected:
+ void num_decrease(int done);
+ void num_increase();
+
+ void thread_run();
+ bool thread_wait_pop(Task*& entry);
+
+ void clear();
+
+ thread_mutex num_mutex;
+ thread_condition_variable num_cond;
+
+ list<Task*> queue;
+ thread_mutex queue_mutex;
+ thread_condition_variable queue_cond;
+
+ int num;
+ bool do_cancel;
+ bool do_exit;
+
+ thread *worker_thread;
+};
+
CCL_NAMESPACE_END
#endif
More information about the Bf-blender-cvs
mailing list