[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() {