From 01f8ace29685a59e3b1a3fcc0a4dce9c5e1a43b5 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 6 May 2017 21:38:18 +0200 Subject: Changed Solver.PARALLEL parameter logic: 0: Parallel processing of solvers disabled 1: One processor parallel processing. Can be used to measure OPENMP overhead >1: Solve n analog subnets in parallel. Previously, all available processors were used which caused performance to degrade on hyperthreading. [Couriersud] --- src/lib/netlist/solver/nld_solver.cpp | 44 ++++++++++------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) (limited to 'src/lib/netlist/solver') diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 01c71aab6f5..f856eeacca9 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -35,9 +35,7 @@ #include "../nl_lists.h" -#if HAS_OPENMP -#include "omp.h" -#endif +#include "../plib/pomp.h" #include "../nl_factory.h" @@ -94,44 +92,26 @@ NETLIB_UPDATE(solver) /* FIXME: Needs a more elegant solution */ bool force_solve = (netlist().time() < netlist_time::from_double(2 * m_params.m_max_timestep)); -#if HAS_OPENMP && USE_OPENMP - if (m_parallel()) - { - const std::size_t t_cnt = m_mat_solvers.size(); - //omp_set_num_threads(3); - //omp_set_dynamic(0); - #pragma omp parallel - { - #pragma omp for - for (int i = 0; i < t_cnt; i++) - if (m_mat_solvers[i]->has_timestep_devices() || force_solve) - { - // Ignore return value - ATTR_UNUSED const netlist_time ts = m_mat_solvers[i]->solve(); - } - } + std::size_t nthreads = std::min(m_parallel(), plib::omp::get_max_threads()); + std::size_t t_cnt = 0; + int solv[128]; + for (int i = 0; i < m_mat_solvers.size(); i++) + if (m_mat_solvers[i]->has_timestep_devices() || force_solve) + solv[t_cnt++] = i; - for (auto & solver : m_mat_solvers) - if (solver->has_timestep_devices() || force_solve) - solver->update_inputs(); + if (nthreads > 1 && t_cnt > 1) + { + plib::omp::set_num_threads(nthreads); + plib::omp::for_static(0, t_cnt, [this, solv](int i) { ATTR_UNUSED const netlist_time ts = this->m_mat_solvers[solv[i]]->solve(); }); } else for (auto & solver : m_mat_solvers) if (solver->has_timestep_devices() || force_solve) - { - // Ignore return value ATTR_UNUSED const netlist_time ts = solver->solve(); - solver->update_inputs(); - } -#else + for (auto & solver : m_mat_solvers) if (solver->has_timestep_devices() || force_solve) - { - // Ignore return value - ATTR_UNUSED const netlist_time ts = solver->solve(); solver->update_inputs(); - } -#endif /* step circuit */ if (!m_Q_step.net().is_queued()) -- cgit v1.2.3-70-g09d2