]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Enable multithreading for end_sweep.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 17 Jan 2000 13:35:53 +0000 (13:35 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 17 Jan 2000 13:35:53 +0000 (13:35 +0000)
git-svn-id: https://svn.dealii.org/trunk@2230 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/include/numerics/time_dependent.h
deal.II/deal.II/source/numerics/time_dependent.cc

index c3d0a35675684a92b1d231db1fc1a6f6b2c22a5d..c3927a9aee62189ec747ed26af22f89eb900859a 100644 (file)
@@ -624,11 +624,40 @@ class TimeDependent
     virtual void start_sweep (const unsigned int sweep_no);
 
                                     /**
-                                     * Analogon to the above function,
-                                     * calling #end_sweep# of each time
-                                     * step object.
+                                     * Analogon to the above
+                                     * function, calling #end_sweep#
+                                     * of each time step object. The
+                                     * same applies with respect to
+                                     * the #virtual#ness of this
+                                     * function as for the previous
+                                     * one.
+                                     *
+                                     * This function does not
+                                     * guarantee that #end_sweep# is
+                                     * called for successive time
+                                     * steps, rather the order of
+                                     * time steps for which the
+                                     * function is called is
+                                     * arbitrary. You should
+                                     * therefore not assume that that
+                                     * function has been called for
+                                     * previous time steps
+                                     * already. If in multithread
+                                     * mode, the #end_sweep# function
+                                     * of several time steps is
+                                     * called at once, so you should
+                                     * use synchronization
+                                     * mechanisms, if your program
+                                     * requires so.
+                                     *
+                                     * The parameter denotes the
+                                     * number of threads that shall
+                                     * be spawned in parallel. It
+                                     * defaults to only one thread,
+                                     * and the value is ignored if
+                                     * not in multithread mode.
                                      */
-    virtual void end_sweep ();
+    virtual void end_sweep (const unsigned int n_threads = 1);
 
                                     /**
                                      * Exception.
@@ -676,7 +705,16 @@ class TimeDependent
                                      * for more information.
                                      */
     const TimeSteppingData timestepping_data_postprocess;  
-    
+
+  private:
+
+                                    /**
+                                     * Do the work of #end_sweep()#
+                                     * for some timesteps only. This
+                                     * is useful in multithread mode.
+                                     */
+    void * end_sweep (const unsigned int begin_timestep,
+                     const unsigned int end_timestep);
 };
 
 
index 5e0f7be8225c30506a055747a55917a47abc2809..cfb3b7a383333546a62b2bab8945a945cda44f25 100644 (file)
@@ -7,6 +7,11 @@
 #include <grid/tria_iterator.h>
 #include <lac/vector.h>
 
+#ifdef DEAL_II_USE_MT
+#  include <base/thread_manager.h>
+#  define NTHREADS 4
+#endif
+
 #include <functional>
 #include <algorithm>
 #include <numeric>
@@ -198,10 +203,48 @@ void TimeDependent::start_sweep (const unsigned int s)
 
 
 
-void TimeDependent::end_sweep ()
+void TimeDependent::end_sweep (const unsigned int
+#ifdef DEAL_II_USE_MT
+                              n_threads
+#endif
+)
 {
-  for (unsigned int step=0; step<timesteps.size(); ++step)
+#ifdef DEAL_II_USE_MT
+                                  // set up the data needed by each
+                                  // thread
+  typedef ThreadManager::Mem_Fun_Data2<TimeDependent,unsigned int,unsigned int> MemFunData;
+  vector<MemFunData> mem_fun_data (n_threads,
+                                  MemFunData(this, 0, 0, &end_sweep));
+  const unsigned int stride = timesteps.size() / n_threads;
+  for (unsigned int i=0; i<n_threads; ++i)
+    {
+      mem_fun_data[i].arg1 = i*stride;
+      mem_fun_data[i].arg2 = (i+1)*stride;
+    };
+  mem_fun_data.back().arg2 = timesteps.size();
+
+                                  // spawn the threads...
+  ThreadManager thread_manager;
+  for (unsigned int i=0; i<n_threads; ++i)
+    thread_manager.spawn (&mem_fun_data[i],
+                         THR_SCOPE_SYSTEM | THR_DETACHED);
+
+                                  // ...and wait for their return
+  thread_manager.wait();
+  
+#else
+  end_sweep (0, timesteps.size());
+#endif
+}
+
+
+
+void * TimeDependent::end_sweep (const unsigned int begin,
+                                const unsigned int end)
+{     
+  for (unsigned int step=begin; step<end; ++step)
     timesteps[step]->end_sweep ();
+  return 0;
 };
   
 

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.