From 3fcdfa0a9b1783f556abe36c9fb927c25c2170ee Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 28 Jun 2020 13:13:57 +0200 Subject: netlist: code maintenance * decrease use of reinterpret_cast. * change some defaults for better ttl game optimization. * various code cleanup. --- src/lib/netlist/nl_base.h | 9 ++++--- src/lib/netlist/plib/mat_cr.h | 26 ++++++++++++++++---- src/lib/netlist/plib/pconfig.h | 19 ++++++++++++--- src/lib/netlist/plib/plists.h | 3 --- src/lib/netlist/plib/pmatrix2d.h | 7 +++++- src/lib/netlist/plib/pmempool.h | 5 ++-- src/lib/netlist/plib/pstream.h | 39 +++++++++++++++++++++++------- src/lib/netlist/plib/ptimed_queue.h | 1 - src/lib/netlist/prg/nlwav.cpp | 4 +-- src/lib/netlist/solver/nld_matrix_solver.h | 2 +- src/lib/netlist/solver/nld_ms_gcr.h | 9 ++++--- src/lib/netlist/solver/nld_solver.cpp | 15 ++++++++---- src/lib/netlist/solver/nld_solver.h | 9 ++++--- 13 files changed, 105 insertions(+), 43 deletions(-) diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index e3e764b6d90..e18c44df9a6 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -1372,7 +1372,7 @@ namespace netlist protected: void changed() noexcept override { - stream()->read(reinterpret_cast(&m_data[0]),1<read(reinterpret_cast(&m_data[0]),1< #include @@ -62,7 +63,7 @@ namespace plib , A(n*n) , nz_num(0) //, nzbd(n * (n+1) / 2) - , nzbd(n) + , m_nzbd(n, n) , m_size(n) { for (std::size_t i=0; i(j)); - nzbd[k].push_back(0); // end of sequence + m_nzbd[k].push_back(narrow_cast(j)); + m_nzbd[k].push_back(0); // end of sequence +#else + for (std::size_t j=k + 1; j < size(); j++) + if (f[j][k] < FILL_INFINITY) + m_nzbd.set(k, m_nzbd.colcount(k), narrow_cast(j)); + m_nzbd.set(k, m_nzbd.colcount(k), 0); // end of sequence +#endif } } @@ -241,10 +249,13 @@ namespace plib A[k] = src.A[k]; } + index_type * nzbd(index_type row) { return m_nzbd[row]; } + index_type nzbd_count(index_type row) { return m_nzbd.colcount(row) - 1; } protected: // FIXME: this should be private // NOLINTNEXTLINE - parray, N > nzbd; // Support for gaussian elimination + //parray, N > m_nzbd; // Support for gaussian elimination + pmatrix2d_vrl m_nzbd; // Support for gaussian elimination private: //parray nzbd; // Support for gaussian elimination std::size_t m_size; @@ -309,9 +320,14 @@ namespace plib std::size_t pi = base::diag[i]; auto f = reciprocal(base::A[pi++]); const std::size_t piie = base::row_idx[i+1]; - const auto &nz = base::nzbd[i]; +#if 0 + const auto &nz = base::m_nzbd[i]; while (auto j = nz[nzbdp++]) // NOLINT(bugprone-infinite-loop) +#else + const auto *nz = base::m_nzbd[i]; + while (auto j = nz[nzbdp++]) // NOLINT(bugprone-infinite-loop) +#endif { // proceed to column i diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 984ed944acb..99643139de7 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -41,7 +41,7 @@ /// Set this to one if you want to use aligned storage optimizations. /// #ifndef PUSE_ALIGNED_OPTIMIZATIONS -#define PUSE_ALIGNED_OPTIMIZATIONS (0) +#define PUSE_ALIGNED_OPTIMIZATIONS (1) #endif /// \brief Use aligned allocations. @@ -63,15 +63,28 @@ /// \brief Number of bytes for cache line alignment /// -#define PALIGN_CACHELINE (16) +#define PALIGN_CACHELINE (64) /// \brief Number of bytes for vector alignment /// -#define PALIGN_VECTOROPT (16) +#define PALIGN_VECTOROPT (32) + +#define PALIGN_MIN_SIZE (16) #define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE) #define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT) +/// brief default minimum alignment of mempool_arena +/// +/// 256 is the best compromise between logic applications like MAME +/// TTL games (e.g. pong) and analog applications like e.g. kidnikik sound. +/// +/// Best performance for pong is achieved with a value of 16, but this degrades +/// kidniki performance by ~10%. +/// +/// More work is needed here. +#define PMEMPOOL_ALIGN (256) + // FIXME: Breaks mame build on windows mingw due to -Wattribute // also triggers -Wattribute on ARM // This is fixed on mingw version 10 diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 4e3ddace57e..f23caa18c2c 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -98,9 +98,6 @@ namespace plib { protected: private: - - // ensure proper alignment - PALIGNAS_VECTOROPT() std::array::type, N> m_buf; unsigned m_initialized; }; diff --git a/src/lib/netlist/plib/pmatrix2d.h b/src/lib/netlist/plib/pmatrix2d.h index b9a2ebee116..0b982b8a034 100755 --- a/src/lib/netlist/plib/pmatrix2d.h +++ b/src/lib/netlist/plib/pmatrix2d.h @@ -214,7 +214,12 @@ namespace plib return m_row[r] + c; } - std::size_t tx() const { return m_v.size(); } + size_type colcount(size_type row) const noexcept + { + return m_row[row + 1] - m_row[row]; + } + + size_type tx() const { return m_v.size(); } private: size_type m_N; diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h index 033a622ff3b..d66efe2abdd 100644 --- a/src/lib/netlist/plib/pmempool.h +++ b/src/lib/netlist/plib/pmempool.h @@ -27,7 +27,7 @@ namespace plib { // Memory pool //============================================================ - template + template class mempool_arena : public arena_base, false, false> { public: @@ -37,7 +37,7 @@ namespace plib { template using base_allocator_type = typename BASEARENA::template allocator_type; - mempool_arena(size_t min_alloc = (1<<21), size_t min_align = PALIGN_CACHELINE) + mempool_arena(size_t min_align = MINALIGN, size_t min_alloc = (1<<21)) : m_min_alloc(min_alloc) , m_min_align(min_align) , m_block_align(1024) @@ -70,6 +70,7 @@ namespace plib { align = m_min_align; size_t rs = size + align; + for (auto &bs : m_blocks) { if (bs->m_free > rs) diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index b96c1f91a3b..dcb2b0652cf 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -27,8 +27,29 @@ namespace plib { + /// \brief wrapper around isteam read + /// + template + static inline S & istream_read(S &is, T * data, size_t len) + { + using ct = typename S::char_type; + static_assert((sizeof(T) % sizeof(ct)) == 0, "istream_read sizeof issue"); + // FIXME: throw on + return is.read(reinterpret_cast(data), gsl::narrow(len * sizeof(T))); + } + + /// \brief wrapper around osteam write + /// + template + static inline S & ostream_write(S &os, const T * data, size_t len) + { + using ct = typename S::char_type; + static_assert((sizeof(T) % sizeof(ct)) == 0, "ostream_write sizeof issue"); + // FIXME: throw on + return os.write(reinterpret_cast(data), gsl::narrow(len * sizeof(T))); + } + /// -/// \brief: putf8reader_t: reader on top of istream. /// /// putf8reader_t digests linux & dos/windows text files /// @@ -188,23 +209,23 @@ public: template void write(const T &val) { - m_strm.write(reinterpret_cast(&val), sizeof(T)); + ostream_write(m_strm, &val, 1); } void write(const pstring &s) { - const auto *const sm = reinterpret_cast(s.c_str()); - const auto sl(static_cast(std::char_traits::length(sm))); + auto *sm = s.c_str(); + const auto sl(std::char_traits::length(sm)); write(sl); - m_strm.write(sm, sl); + ostream_write(m_strm, sm, sl); } template void write(const std::vector &val) { - const auto sz(static_cast(val.size())); + const auto sz(val.size()); write(sz); - m_strm.write(reinterpret_cast(val.data()), sz * gsl::narrow(sizeof(T))); + ostream_write(m_strm, val.data(), sz); } private: @@ -225,7 +246,7 @@ public: template void read(T &val) { - m_strm.read(reinterpret_cast(&val), gsl::narrow(sizeof(T))); + istream_read(m_strm, &val, 1); } void read( pstring &s) @@ -244,7 +265,7 @@ public: std::size_t sz = 0; read(sz); val.resize(sz); - m_strm.read(reinterpret_cast(val.data()), gsl::narrow(sizeof(T) * sz)); + istream_read(m_strm, val.data(), sz); } private: diff --git a/src/lib/netlist/plib/ptimed_queue.h b/src/lib/netlist/plib/ptimed_queue.h index dffc969e9c6..2ec158f316e 100644 --- a/src/lib/netlist/plib/ptimed_queue.h +++ b/src/lib/netlist/plib/ptimed_queue.h @@ -217,7 +217,6 @@ namespace plib { using lock_guard_type = std::lock_guard; mutex_type m_lock; - PALIGNAS_CACHELINE() T * m_end; aligned_vector m_list; diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 2317495c677..9a9b3f08e69 100755 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -76,9 +76,7 @@ public: template void write(const T &val) { - static_assert(sizeof(std::ostream::char_type) == 1, "char_type size must be 1"); - const auto *ptr(reinterpret_cast(&val)); - m_f.write(ptr, sizeof(T)); + plib::ostream_write(m_f, &val, 1); } template diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 6a769775248..3fd0e2fd6d9 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -185,7 +185,7 @@ namespace solver public: using list_t = std::vector; using fptype = nl_fptype; - using arena_type = plib::mempool_arena; + using arena_type = plib::mempool_arena; // after every call to solve, update inputs must be called. // this can be done as well as a batch to ease parallel processing. diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index 3de955627ee..fb5c675dd14 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -200,9 +200,11 @@ namespace solver for (std::size_t i = 0; i < iN - 1; i++) { - const auto &nzbd = this->m_terms[i].m_nzbd; + //const auto &nzbd = this->m_terms[i].m_nzbd; + const auto *nzbd = mat.nzbd(i); + const auto nzbd_count = mat.nzbd_count(i); - if (!nzbd.empty()) + if (nzbd_count > 0) { std::size_t pi = mat.diag[i]; @@ -212,8 +214,9 @@ namespace solver const std::size_t piie = mat.row_idx[i+1]; //for (auto & j : nzbd) - for (std::size_t j : nzbd) + for (std::size_t jj = 0; jj < nzbd_count; jj++) { + std::size_t j = nzbd[jj]; // proceed to column i std::size_t pj = mat.row_idx[j]; diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 4e0d8f4c4b3..b38616945f9 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -81,17 +81,20 @@ namespace devices } } + //using solver_ptr = host_arena::unique_ptr; + // FIXME: should be created in device space template - host_arena::unique_ptr create_it(netlist_state_t &nl, pstring name, + NETLIB_NAME(solver)::solver_ptr create_it(netlist_state_t &nl, pstring name, analog_net_t::list_t &nets, solver::solver_parameters_t ¶ms, std::size_t size) { return plib::make_unique(nl, name, nets, ¶ms, size); + //return nl.make_pool_object(nl, name, nets, ¶ms, size); } template - host_arena::unique_ptr NETLIB_NAME(solver)::create_solver(std::size_t size, + NETLIB_NAME(solver)::solver_ptr NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername, analog_net_t::list_t &nets) { @@ -124,11 +127,11 @@ namespace devices return create_it>(state(), solvername, nets, m_params, size); #endif } - return host_arena::unique_ptr(); + return solver_ptr(); } template - host_arena::unique_ptr NETLIB_NAME(solver)::create_solvers( + NETLIB_NAME(solver)::solver_ptr NETLIB_NAME(solver)::create_solvers( const pstring &sname, analog_net_t::list_t &nets) { @@ -137,8 +140,10 @@ namespace devices { case 1: return plib::make_unique, host_arena>(state(), sname, nets, &m_params); + //return state().make_pool_object>(state(), sname, nets, &m_params); case 2: return plib::make_unique, host_arena>(state(), sname, nets, &m_params); + //return state().make_pool_object>(state(), sname, nets, &m_params); case 3: return create_solver(3, sname, nets); case 4: @@ -291,7 +296,7 @@ namespace devices log().verbose("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size()); for (auto & grp : splitter.groups) { - host_arena::unique_ptr ms; + solver_ptr ms; pstring sname = plib::pfmt("Solver_{1}")(m_mat_solvers.size()); switch (m_params.m_fp_type()) diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index e9734af1520..f1395543524 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -47,23 +47,26 @@ namespace devices NETLIB_RESETI(); // NETLIB_UPDATE_PARAMI(); + //using solver_ptr = device_arena::unique_ptr; + using solver_ptr = host_arena::unique_ptr; + private: logic_input_t m_fb_step; logic_output_t m_Q_step; // FIXME: these should be created in device space - std::vector> m_mat_solvers; + std::vector m_mat_solvers; std::vector m_mat_solvers_all; std::vector m_mat_solvers_timestepping; solver::solver_parameters_t m_params; template - host_arena::unique_ptr create_solver(std::size_t size, + solver_ptr create_solver(std::size_t size, const pstring &solvername, analog_net_t::list_t &nets); template - host_arena::unique_ptr create_solvers( + solver_ptr create_solvers( const pstring &sname, analog_net_t::list_t &nets); }; -- cgit v1.2.3