summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/solver
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-06-13 15:48:14 +0200
committer couriersud <couriersud@gmx.org>2020-06-13 15:48:14 +0200
commita48f64e01849af2a26fe1f5538cd1777acb18ea8 (patch)
tree201814ccfe5868e1064afd2ef76b05909dd7018b /src/lib/netlist/solver
parentd9d432b379de0ed82923ef1a6f7a7e6e399300a1 (diff)
netlist: Improve static solver performance by 5%. [Couriersud]
Use a more condensed matrix format for go, gt and Id matrices. In addition, optimize the static compilation code.
Diffstat (limited to 'src/lib/netlist/solver')
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp11
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h7
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h51
3 files changed, 61 insertions, 8 deletions
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index b5b2adf2245..aeb5d11055f 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -375,6 +375,17 @@ namespace solver
m_Idrn.resize(iN, max_count);
m_connected_net_Vn.resize(iN, max_count);
+ // Initialize arrays to 0 (in case the vrl one is used
+ for (std::size_t k = 0; k < iN; k++)
+ for (std::size_t j = 0; j < m_terms[k].count(); j++)
+ {
+ m_gtn.set(k,j, nlconst::zero());
+ m_gonn.set(k,j, nlconst::zero());
+ m_Idrn.set(k,j, nlconst::zero());
+ m_connected_net_Vn.set(k, j, nullptr);
+ }
+
+
for (std::size_t k = 0; k < iN; k++)
{
auto count = m_terms[k].count();
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index fef3ec4a29b..606ccbb9ee2 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -274,10 +274,17 @@ namespace solver
virtual bool check_err() = 0;
virtual void store() = 0;
+#if 0
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gonn;
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gtn;
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_Idrn;
plib::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_connected_net_Vn;
+#else
+ plib::pmatrix2d_vrl<nl_fptype, aligned_alloc<nl_fptype>> m_gonn;
+ plib::pmatrix2d_vrl<nl_fptype, aligned_alloc<nl_fptype>> m_gtn;
+ plib::pmatrix2d_vrl<nl_fptype, aligned_alloc<nl_fptype>> m_Idrn;
+ plib::pmatrix2d_vrl<nl_fptype *, aligned_alloc<nl_fptype *>> m_connected_net_Vn;
+#endif
plib::aligned_vector<terms_for_net_t> m_terms;
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index 72e5c45f525..6c7f5d7e502 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -139,7 +139,7 @@ namespace solver
pstring fpsuffix(fp_constants<FT>::suffix());
for (std::size_t i = 0; i < mat.nz_num; i++)
- strm("{1} m_A{2}(0.0);\n", fptype, i, i);
+ strm("\t{1} m_A{2}(0.0);\n", fptype, i, i);
for (std::size_t k = 0; k < iN; k++)
{
@@ -150,23 +150,27 @@ namespace solver
//auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<FT>::zero());
//*tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
auto pd = this->m_mat_ptr[k][net.railstart()] - &this->mat.A[0];
+#if 0
pstring terms = plib::pfmt("m_A{1} = gt[{2}]")(pd, this->m_gtn.didx(k,0));
for (std::size_t i=1; i < net.count(); i++)
terms += plib::pfmt(" + gt[{1}]")(this->m_gtn.didx(k,i));
strm("\t{1};\n", terms);
-
+#else
+ for (std::size_t i=0; i < net.count(); i++)
+ strm("\tm_A{1} += gt[{2}];\n", pd, this->m_gtn.didx(k,i));
+#endif
//for (std::size_t i = 0; i < railstart; i++)
// *tcr_r[i] += static_cast<FT>(go[i]);
for (std::size_t i = 0; i < net.railstart(); i++)
{
auto p = this->m_mat_ptr[k][i] - &this->mat.A[0];
- strm("\tm_A{1} = m_A{1} + go[{2}];\n", p, this->m_gonn.didx(k,i));
+ strm("\tm_A{1} += go[{2}];\n", p, this->m_gonn.didx(k,i));
}
+#if 0
//auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero()));
-
terms = plib::pfmt("{1} RHS{2} = Idr[{3}]")(fptype, k, this->m_Idrn.didx(k,0));
for (std::size_t i=1; i < net.count(); i++)
terms += plib::pfmt(" + Idr[{1}]")(this->m_Idrn.didx(k,i));
@@ -174,9 +178,21 @@ namespace solver
// RHS_t += (- go[i]) * *cnV[i];
for (std::size_t i = net.railstart(); i < net.count(); i++)
- terms += plib::pfmt(" - go[{1}] * *cnV[{1}]")(this->m_gonn.didx(k,i), this->m_connected_net_Vn.didx(k,i));
+ terms += plib::pfmt(" - go[{1}] * *cnV[{2}]")(this->m_gonn.didx(k,i), this->m_connected_net_Vn.didx(k,i));
strm("\t{1};\n", terms);
+#else
+ //auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero()));
+ strm("\t{1} RHS{2} = Idr[{3}];\n", fptype, k, this->m_Idrn.didx(k,0));
+ for (std::size_t i=1; i < net.count(); i++)
+ strm("\tRHS{1} += Idr[{2}];\n", k, this->m_Idrn.didx(k,i));
+ //for (std::size_t i = railstart; i < term_count; i++)
+ // RHS_t += (- go[i]) * *cnV[i];
+
+ for (std::size_t i = net.railstart(); i < net.count(); i++)
+ strm("\tRHS{1} -= go[{2}] * *cnV[{3}];\n", k, this->m_gonn.didx(k,i), this->m_connected_net_Vn.didx(k,i));
+
+#endif
}
for (std::size_t i = 0; i < iN - 1; i++)
@@ -188,7 +204,7 @@ namespace solver
std::size_t pi = mat.diag[i];
//const FT f = 1.0 / m_A[pi++];
- strm("const {1} f{2} = 1.0{3} / m_A{4};\n", fptype, i, fpsuffix, pi);
+ strm("\tconst {1} f{2} = 1.0{3} / m_A{4};\n", fptype, i, fpsuffix, pi);
pi++;
const std::size_t piie = mat.row_idx[i+1];
@@ -224,6 +240,7 @@ namespace solver
strm("\tV[{1}] = RHS{2} / m_A{3};\n", iN - 1, iN - 1, mat.diag[iN - 1]);
for (std::size_t j = iN - 1; j-- > 0;)
{
+#if 1
strm("\t{1} tmp{2} = 0.0{3};\n", fptype, j, fpsuffix);
const std::size_t e = mat.row_idx[j+1];
for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++)
@@ -231,6 +248,24 @@ namespace solver
strm("\ttmp{1} += m_A{2} * V[{3}];\n", j, pk, mat.col_idx[pk]);
}
strm("\tV[{1}] = (RHS{1} - tmp{1}) / m_A{4};\n", j, j, j, mat.diag[j]);
+#else
+ pstring tmp;
+ const std::size_t e = mat.row_idx[j+1];
+ for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++)
+ {
+ tmp = tmp + plib::pfmt(" + m_A{2} * V[{3}]")(j, pk, mat.col_idx[pk]);
+ }
+ if (tmp.empty())
+ {
+ strm("\tV[{1}] = RHS{1} / m_A{2};\n", j, mat.diag[j]);
+ }
+ else
+ {
+ //strm("\tconst {1} tmp{2} = {3};\n", fptype, j, tmp.substr(3));
+ //strm("\tV[{1}] = (RHS{1} - tmp{1}) / m_A{2};\n", j, mat.diag[j]);
+ strm("\tV[{1}] = (RHS{1} - ({2})) / m_A{3};\n", j, tmp.substr(3), mat.diag[j]);
+ }
+#endif
}
}
@@ -263,8 +298,8 @@ namespace solver
else if (target == CXX_STATIC)
extqual = "static";
strm.writeline(plib::pfmt("{1} void {2}({3} * __restrict V, "
- "{4} * __restrict go, {4} * __restrict gt, "
- "{4} * __restrict Idr, {4} ** __restrict cnV)\n")(extqual, name, str_floattype, str_fptype));
+ "const {4} * __restrict go, const {4} * __restrict gt, "
+ "const {4} * __restrict Idr, const {4} * const * __restrict cnV)\n")(extqual, name, str_floattype, str_fptype));
strm.writeline("{\n");
generate_code(strm);
strm.writeline("}\n");