From 092c407b3695662724d29b2ede48478ba58a8a71 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Sun, 15 Feb 2015 13:55:32 -0600 Subject: [PATCH] Update a few comments that relate to set_thread_limit(). --- doc/doxygen/headers/multithreading.h | 37 +++++++++++-------------- include/deal.II/base/mpi.h | 7 +++++ include/deal.II/base/multithread_info.h | 26 ++++++++++------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/doc/doxygen/headers/multithreading.h b/doc/doxygen/headers/multithreading.h index bf5e29479b..9442d9d7af 100644 --- a/doc/doxygen/headers/multithreading.h +++ b/doc/doxygen/headers/multithreading.h @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2006 - 2014 by the deal.II authors +// Copyright (C) 2006 - 2015 by the deal.II authors // // This file is part of the deal.II library. // @@ -1211,27 +1211,22 @@ * number of threads explicitly. However, on large symmetric multiprocessing * (SMP) machines, especially ones with a resource/job manager or on systems * on which access to some parts of the memory is possible but very expensive - * for processors far away (e.g. large NUMA SMP machines), it may be necessary + * for processors far away (e.g. very large NUMA SMP machines), it may be necessary * to explicitly set the number of threads to prevent the TBB from using too - * many CPUs. In this case the following commands can be used: - * @code - #include - - // 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); - * @endcode - * The method of setting the number of threads relies on this call to - * task_scheduler_init occurring before any other calls to the - * TBB functions. If this call is first, it will set the number of threads - * used by TBB for the remainder of the program. Notice that the call starts - * one less thread than the argument, since the main thread is counted. If - * this method does not seem successful (gdb can be used to see when and how - * many threads are started), ensure that the call is early enough in the - * program (for example right at the start of main()), and check - * that there are no other libraries starting threads. - * - * Note that a small number of places inside deal.II also uses thread-based + * many CPUs. Another use case is if you run multiple MPI jobs on a single + * machine and each job should only use a subset of the available processor + * cores. + * + * Setting the number of threads explicitly is done by calling + * MultithreadInfo::set_thread_limit() before any other calls to functions + * that may create threads. In practice, it should be one of the first + * functions you call in main(). + * + * If you run your program with MPI, then you can use the optional third + * argument to the constructor of the MPI_InitFinalize class to achieve the + * same goal. + * + * @note A small number of places inside deal.II also uses thread-based * parallelism explicitly, for example for running background tasks that have * to wait for input or output to happen and consequently do not consume * much CPU time. Such threads do not run under the control of the TBB diff --git a/include/deal.II/base/mpi.h b/include/deal.II/base/mpi.h index 726229d014..0f2bf7f21f 100644 --- a/include/deal.II/base/mpi.h +++ b/include/deal.II/base/mpi.h @@ -305,6 +305,13 @@ namespace Utilities * that will really be created will be the minimum of the argument * passed here, the environment variable (if set), and the number of * cores accessible to the thread. + * + * @note MultithreadInfo::set_thread_limit() can only work if it is + * called before any threads are created. The safest place for a call to + * it is therefore at the beginning of + * main(). Consequently, this extends to the current class: + * the best place to create an object of this type is also at or close + * to the top of main(). */ MPI_InitFinalize (int &argc, char ** &argv, diff --git a/include/deal.II/base/multithread_info.h b/include/deal.II/base/multithread_info.h index f32677b46d..5863f9e2ba 100644 --- a/include/deal.II/base/multithread_info.h +++ b/include/deal.II/base/multithread_info.h @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2000 - 2014 by the deal.II authors +// Copyright (C) 2000 - 2015 by the deal.II authors // // This file is part of the deal.II library. // @@ -81,16 +81,22 @@ public: static std::size_t memory_consumption (); /** - * Sets the maximum number of threads to be used to the minimum of the - * environment variable DEAL_II_NUM_THREADS and the given parameter (if not - * the default value). This affects the initialization of the TBB. If - * neither is given, the default from TBB is used (based on the number of - * cores in the system). + * Set the maximum number of threads to be used to the minimum of the + * environment variable DEAL_II_NUM_THREADS and the given argument (or its + * default value). This affects the initialization of the TBB. If neither is + * given, the default from TBB is used (based on the number of cores in the + * system). * - * This routine is called automatically by MPI_InitFinalize. Due to - * limitations in the way TBB can be controlled, only the first call to this - * method will have any effect. Use the parameter of the MPI_InitFinalize if - * you have an MPI based code. + * Due to limitations in the way TBB can be controlled, only the first call + * to this method will have any effect. In practice, this means that you + * need to call this function before you get to any point in your program + * where multiple threads may be created. In other words, the correct place + * for a call to this function is at the top of your main() + * function. + * + * This routine is called automatically by MPI_InitFinalize. Use the + * appropriate argument of the constructor of MPI_InitFinalize if you have + * an MPI based code. */ static void set_thread_limit (const unsigned int max_threads = numbers::invalid_unsigned_int); -- 2.39.5