getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] (no subject)


From: Andriy Andreykiv
Subject: [Getfem-commits] (no subject)
Date: Wed, 16 Jan 2019 09:56:18 -0500 (EST)

branch: static_initialization_for_singleton_instance_pointer
commit dcd7d3938a1f2bdfeee8c42a33b35100cce29011
Author: Andriy.Andreykiv <address@hidden>
Date:   Wed Jan 16 15:56:02 2019 +0100

    improving multi-threaded performance by reducing the usage of muteces when 
the shared data hasn't changed.
---
 src/bgeot_geometric_trans.cc                       |  6 ++--
 src/dal_static_stored_objects.cc                   |  4 +--
 src/getfem/getfem_fem.h                            | 38 +++++++++++-----------
 src/getfem/getfem_omp.h                            | 18 ++++++----
 ...fem_generic_assembly_functions_and_operators.cc |  9 ++---
 src/getfem_omp.cc                                  | 14 +++++---
 6 files changed, 50 insertions(+), 39 deletions(-)

diff --git a/src/bgeot_geometric_trans.cc b/src/bgeot_geometric_trans.cc
index 1ea29e9..0b1cc6a 100644
--- a/src/bgeot_geometric_trans.cc
+++ b/src/bgeot_geometric_trans.cc
@@ -506,7 +506,8 @@ namespace bgeot {
     mutable bool hess_computed_ = false;
 
     void compute_grad_() const {
-      auto guard = getfem::omp_guard{};
+      if (grad_computed_) return;
+      GLOBAL_OMP_GUARD
       if (grad_computed_) return;
       size_type R = trans.size();
       dim_type n = dim();
@@ -521,7 +522,8 @@ namespace bgeot {
     }
 
     void compute_hess_() const {
-      auto guard = getfem::omp_guard{};
+      if (hess_computed_) return;
+      GLOBAL_OMP_GUARD
       if (hess_computed_) return;
       size_type R = trans.size();
       dim_type n = dim();
diff --git a/src/dal_static_stored_objects.cc b/src/dal_static_stored_objects.cc
index 38810f5..fbe5f21 100644
--- a/src/dal_static_stored_objects.cc
+++ b/src/dal_static_stored_objects.cc
@@ -310,8 +310,8 @@ namespace dal {
 
   void del_stored_objects(std::list<pstatic_stored_object> &to_delete,
                           bool ignore_unstored) {
-    getfem::omp_guard lock;
-    GMM_NOPERATION(lock);
+
+    GLOBAL_OMP_GUARD
 
     ON_STORED_DEBUG(if (dal_static_stored_tab_valid__) return);
 
diff --git a/src/getfem/getfem_fem.h b/src/getfem/getfem_fem.h
index a6e1a95..8e71614 100644
--- a/src/getfem/getfem_fem.h
+++ b/src/getfem/getfem_fem.h
@@ -501,42 +501,44 @@ namespace getfem {
   protected :
     std::vector<FUNC> base_;
     mutable std::vector<std::vector<FUNC>> grad_, hess_;
-    mutable bool grad_computed_;
-    mutable bool hess_computed_;
+    mutable bool grad_computed_ = false;
+    mutable bool hess_computed_ = false;
 
     void compute_grad_() const {
-      auto guard = getfem::omp_guard{};
+      if (grad_computed_) return;
+      GLOBAL_OMP_GUARD
       if (grad_computed_) return;
       size_type R = nb_base_components(0);
       dim_type n = dim();
       grad_.resize(R);
       for (size_type i = 0; i < R; ++i) {
-       grad_[i].resize(n);
-       for (dim_type j = 0; j < n; ++j) {
-         grad_[i][j] = base_[i]; grad_[i][j].derivative(j);
-       }
+        grad_[i].resize(n);
+        for (dim_type j = 0; j < n; ++j) {
+          grad_[i][j] = base_[i]; grad_[i][j].derivative(j);
+        }
       }
       grad_computed_ = true;
     }
 
     void compute_hess_() const {
-      auto guard = getfem::omp_guard{};
+      if (hess_computed_) return;
+      GLOBAL_OMP_GUARD
       if (hess_computed_) return;
       size_type R = nb_base_components(0);
       dim_type n = dim();
       hess_.resize(R);
       for (size_type i = 0; i < R; ++i) {
-       hess_[i].resize(n*n);
-       for (dim_type j = 0; j < n; ++j) {
-         for (dim_type k = 0; k < n; ++k) {
-           hess_[i][j+k*n] = base_[i];
-           hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
-         }
-       }
+        hess_[i].resize(n*n);
+        for (dim_type j = 0; j < n; ++j) {
+          for (dim_type k = 0; k < n; ++k) {
+            hess_[i][j+k*n] = base_[i];
+            hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
+          }
+        }
       }
       hess_computed_ = true;
     }
-    
+
   public :
 
     /// Gives the array of basic functions (components).
@@ -586,8 +588,6 @@ namespace getfem {
            *it = bgeot::to_scalar(hess_[i][j+k*n].eval(x.begin()));
     }
 
-    fem() : grad_computed_(false), hess_computed_(false){}
-
   };
 
   /** Classical polynomial FEM. */
@@ -858,7 +858,7 @@ namespace getfem {
 
     gmm::clear(val);
     base_tensor Z; real_base_value(c, Z);
-    
+
     for (size_type j = 0; j < nbdof; ++j) {
       for (size_type q = 0; q < Qmult; ++q) {
         typename gmm::linalg_traits<CVEC>::value_type co = coeff[j*Qmult+q];
diff --git a/src/getfem/getfem_omp.h b/src/getfem/getfem_omp.h
index ca1aec6..e9ddeac 100644
--- a/src/getfem/getfem_omp.h
+++ b/src/getfem/getfem_omp.h
@@ -58,13 +58,14 @@ namespace getfem
 #ifdef GETFEM_HAS_OPENMP
   //declaring a thread lock, to protect multi-threaded accesses to
   //asserts, traces and warnings. Using a global mutex
-  class omp_guard: public std::lock_guard<std::recursive_mutex>
+  class omp_guard
   {
   public:
     omp_guard();
 
   private:
-    static std::recursive_mutex mutex_;
+    std::unique_ptr<std::lock_guard<std::recursive_mutex>> plock;
+    static std::recursive_mutex mutex;
   };
 
   //like std::lock_guard, but copyable
@@ -74,8 +75,8 @@ namespace getfem
     local_guard(std::recursive_mutex&);
 
   private:
-    std::recursive_mutex& mutex_;
-    std::shared_ptr<std::lock_guard<std::recursive_mutex>> plock_;
+    std::recursive_mutex& mutex;
+    std::shared_ptr<std::lock_guard<std::recursive_mutex>> plock;
   };
 
   //produces scoped lock on the
@@ -88,9 +89,10 @@ namespace getfem
     //on the mutex from this factory
     local_guard get_lock() const;
   private:
-    mutable std::recursive_mutex mutex_;
+    mutable std::recursive_mutex mutex;
   };
 
+  #define GLOBAL_OMP_GUARD getfem::omp_guard g; GMM_NOPERATION_(abs(&(g) != 
&(g)));
 
 #else
 
@@ -100,6 +102,8 @@ namespace getfem
   {
     inline local_guard get_lock() const {return local_guard();}
   };
+  #define GLOBAL_OMP_GUARD
+
 #endif
 
   /**set maximum number of OpenMP threads*/
@@ -206,8 +210,8 @@ namespace getfem
       }
 
       void on_thread_update() {
-        std::unique_ptr<omp_guard> p_guard = nullptr;
-        if (me_is_multithreaded_now()) p_guard = std::make_unique<omp_guard>();
+        if (thread_values.size() == thread_policy::num_threads()) return;
+        GLOBAL_OMP_GUARD
         if (thread_values.size() != thread_policy::num_threads()) {
           thread_values.resize(thread_policy::num_threads());
         }
diff --git a/src/getfem_generic_assembly_functions_and_operators.cc 
b/src/getfem_generic_assembly_functions_and_operators.cc
index 1b3a056..3193528 100644
--- a/src/getfem_generic_assembly_functions_and_operators.cc
+++ b/src/getfem_generic_assembly_functions_and_operators.cc
@@ -605,7 +605,8 @@ namespace getfem {
   void ga_define_function(const std::string &name, size_type nbargs,
                           const std::string &expr, const std::string &der1,
                           const std::string &der2) {
-    auto guard = omp_guard{};
+
+    GLOBAL_OMP_GUARD
 
     auto &PREDEF_FUNCTIONS = 
dal::singleton<ga_predef_function_tab>::instance(0);
     if(PREDEF_FUNCTIONS.find(name) != PREDEF_FUNCTIONS.end()) return;
@@ -646,7 +647,7 @@ namespace getfem {
 
   void ga_define_function(const std::string &name, pscalar_func_onearg f,
                           const std::string &der) {
-    auto guard = omp_guard{};
+    GLOBAL_OMP_GUARD
     ga_predef_function_tab &PREDEF_FUNCTIONS
       = dal::singleton<ga_predef_function_tab>::instance(0);
     PREDEF_FUNCTIONS[name] = ga_predef_function(f, 1, der);
@@ -657,7 +658,7 @@ namespace getfem {
 
   void ga_define_function(const std::string &name, pscalar_func_twoargs f,
                           const std::string &der1, const std::string &der2) {
-    auto guard = omp_guard{};
+    GLOBAL_OMP_GUARD
     ga_predef_function_tab &PREDEF_FUNCTIONS
       = dal::singleton<ga_predef_function_tab>::instance(0);
     PREDEF_FUNCTIONS[name] = ga_predef_function(f, 1, der1, der2);
@@ -669,7 +670,7 @@ namespace getfem {
   }
 
   void ga_undefine_function(const std::string &name) {
-    auto guard = omp_guard{};
+    GLOBAL_OMP_GUARD
     ga_predef_function_tab &PREDEF_FUNCTIONS
       = dal::singleton<ga_predef_function_tab>::instance(0);
     ga_predef_function_tab::iterator it = PREDEF_FUNCTIONS.find(name);
diff --git a/src/getfem_omp.cc b/src/getfem_omp.cc
index 28159b9..c127e96 100644
--- a/src/getfem_omp.cc
+++ b/src/getfem_omp.cc
@@ -34,19 +34,23 @@ namespace getfem{
 
 #ifdef GETFEM_HAS_OPENMP
 
-  std::recursive_mutex omp_guard::mutex_;
+  std::recursive_mutex omp_guard::mutex;
 
   omp_guard::omp_guard()
-    : std::lock_guard<std::recursive_mutex>(mutex_)
+    : plock{me_is_multithreaded_now() ?
+       std::make_unique<std::lock_guard<std::recursive_mutex>>(mutex)
+      : nullptr}
   {}
 
   local_guard::local_guard(std::recursive_mutex& m) :
-    mutex_(m),
-    plock_(std::make_shared<std::lock_guard<std::recursive_mutex>>(m))
+    mutex{m},
+    plock{me_is_multithreaded_now() ?
+      std::make_shared<std::lock_guard<std::recursive_mutex>>(m)
+      : nullptr}
   {}
 
   local_guard lock_factory::get_lock() const{
-    return local_guard(mutex_);
+    return local_guard{mutex};
   }
 
   size_type global_thread_policy::this_thread() {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]