]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Add a section on what happens when you try to synchronize tasks.
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Sat, 27 Nov 2010 00:33:29 +0000 (00:33 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Sat, 27 Nov 2010 00:33:29 +0000 (00:33 +0000)
git-svn-id: https://svn.dealii.org/trunk@22864 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/doxygen/headers/multithreading.h

index d671c516cd70dbd9f4eee63e7969e03e4ec990fa..3d65290de09e936ff2221de4ddac377338d6b484 100644 (file)
@@ -57,6 +57,7 @@
  *  <li> @ref MTSimpleLoops "Abstractions for tasks: Simple loops"
  *  <li> @ref MTComplexLoops "Abstractions for tasks: More complex loops"
  *  <li> @ref MTWorkStream "Abstractions for tasks: Work streams"
+ *  <li> @ref MTTasksSynchronization ""
  *  <li> @ref MTThreads "Thread-based parallelism"
  *  <li> @ref MTTaskThreads "Controlling the number of threads used for tasks"
  * </ol> </td> </tr> </table>
  * tutorial programs.
  *
  *
+ * @anchor MTTasksSynchronization
+ * <h3>Tasks and synchronization</h3>
+ *
+ * Tasks are powerful but they do have their limitation: to make
+ * things efficient, the task scheduler never interrupts tasks by
+ * itself. With the exception of the situation where one calls the
+ * Threads::Task::join function to wait for another task to finish,
+ * the task scheduler always runs a task to completion. The downside
+ * is that the scheduler does not see if a task is actually idling,
+ * for example if it waits for something else to happen (file IO to
+ * finish, input from the keyboard, etc). In cases like this, the task
+ * scheduler could in principle run a different task, but since it
+ * doesn't know what tasks are doing it doesn't. Functions that do
+ * wait for external events to happen are therefore not good
+ * candidates for tasks and should use threads (see below).
+ *
+ * However, there are cases where tasks are not only a bad abstraction
+ * for a job but can actually not be used: As a matter of principle,
+ * tasks can not synchronize with other tasks through the use of a
+ * mutex or a condition variable (see the Threads::Mutex and
+ * Threads::ConditionVariable classes). The reason is that if task A
+ * needs to wait for task B to finish something, then this is only
+ * going to work if there is a guarantee that task B will eventually
+ * be able to run and finish the task. Now imagine that you have 2
+ * processors, and tasks A1 and A2 are currently running; let's assume
+ * that they have queued tasks B1 and B2, and are now waiting with a
+ * mutex for these queued tasks to finish (part of) their work. Since
+ * the machine has only two processors, the task scheduler will only
+ * start B1 or B2 once either A1 or A2 are done -- but this isn't
+ * happening since they are waiting using operating system resources
+ * (a mutex) rather than task scheduler resources. The result is a
+ * deadlock.
+ *
+ * The bottom line is that tasks can not use mutices or condition
+ * variables to synchronize with other tasks. If synchronization is
+ * necessary, you need to use threads because the operating system
+ * makes sure that all threads eventually get to run, independent of
+ * the total number of threads.
+ *
+ *
  * @anchor MTThreads
  * <h3>Thread-based parallelism</h3>
  *
  * section on
  * @ref MTHow "How scheduling tasks works and when task-based programming is not efficient"
  * above. Primarily, jobs that are not able to fully utilize the CPU are bad
- * fits for tasks.
+ * fits for tasks as discussed above.
  *
  * In a case like this, you can resort to explicitly start threads, rather
  * than tasks, using pretty much the same syntax as above. For example, if you
 
    // In the program, before any task-based parallelism is reached.
    // Early in the main method is a good place to call this:
-   tbb::task_scheduler_init init(n_desired_threads + 1); 
+   tbb::task_scheduler_init init(n_desired_threads + 1);
  * @endcode
  * The method of setting the number of threads relies on this call to
  * <code>task_scheduler_init</code> occurring before any other calls to the

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.