summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatarGravatar couriersud <couriersud@gmx.org>2020-06-28 13:13:57 +0200
committerGravatarGravatar couriersud <couriersud@gmx.org>2020-06-28 13:14:42 +0200
commit3fcdfa0a9b1783f556abe36c9fb927c25c2170ee (patch) (github)
tree321f4d3c3e080448f020ee3d037abe6b453a511e
parent3832644d4ad36d5b5807b3d2d9ff6d284bd86236 (diff)
downloadmame-3fcdfa0a9b1783f556abe36c9fb927c25c2170ee.tar.bz2
mame-3fcdfa0a9b1783f556abe36c9fb927c25c2170ee.zip
netlist: code maintenance
* decrease use of reinterpret_cast. * change some defaults for better ttl game optimization. * various code cleanup.
-rw-r--r--src/lib/netlist/nl_base.h9
-rw-r--r--src/lib/netlist/plib/mat_cr.h26
-rw-r--r--src/lib/netlist/plib/pconfig.h19
-rw-r--r--src/lib/netlist/plib/plists.h3
-rwxr-xr-xsrc/lib/netlist/plib/pmatrix2d.h7
-rw-r--r--src/lib/netlist/plib/pmempool.h5
-rw-r--r--src/lib/netlist/plib/pstream.h39
-rw-r--r--src/lib/netlist/plib/ptimed_queue.h1
-rwxr-xr-xsrc/lib/netlist/prg/nlwav.cpp4
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h2
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h9
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp15
-rw-r--r--src/lib/netlist/solver/nld_solver.h9
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<std::istream::char_type *>(&m_data[0]),1<<AW);
+ plib::istream_read(*stream(), m_data.data(), 1<<AW);
}
private:
@@ -1940,11 +1940,12 @@ namespace netlist
devices::NETLIB_NAME(solver) * m_solver;
// mostly rw
- PALIGNAS_CACHELINE()
+ //PALIGNAS(16)
netlist_time_ext m_time;
devices::NETLIB_NAME(mainclock) * m_mainclock;
- PALIGNAS_CACHELINE()
+ //PALIGNAS_CACHELINE()
+ //PALIGNAS(16)
detail::queue_t m_queue;
bool m_use_stats;
// performance
@@ -2552,7 +2553,7 @@ namespace netlist
auto f = stream();
if (f != nullptr)
{
- f->read(reinterpret_cast<std::istream::char_type *>(&m_data[0]),1<<AW);
+ plib::istream_read(*f, m_data.data(), 1<<AW);
// FIXME: check for failbit if not in validation.
}
else
diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h
index 2da661d39d7..0f21aff2326 100644
--- a/src/lib/netlist/plib/mat_cr.h
+++ b/src/lib/netlist/plib/mat_cr.h
@@ -18,6 +18,7 @@
#include "pstate.h"
#include "ptypes.h"
#include "putil.h"
+#include "pmatrix2d.h"
#include <algorithm>
#include <array>
@@ -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<n+1; i++)
@@ -148,10 +149,17 @@ namespace plib
for (std::size_t k=0; k < size(); k++)
{
+#if 0
for (std::size_t j=k + 1; j < size(); j++)
if (f[j][k] < FILL_INFINITY)
- nzbd[k].push_back(narrow_cast<C>(j));
- nzbd[k].push_back(0); // end of sequence
+ m_nzbd[k].push_back(narrow_cast<C>(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<C>(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<std::vector<index_type>, N > nzbd; // Support for gaussian elimination
+ //parray<std::vector<index_type>, N > m_nzbd; // Support for gaussian elimination
+ pmatrix2d_vrl<index_type> m_nzbd; // Support for gaussian elimination
private:
//parray<C, N < 0 ? -N * (N-1) / 2 : N * (N+1) / 2 > 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<typename std::aligned_storage<sizeof(C), alignof(C)>::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 <typename BASEARENA>
+ template <typename BASEARENA, std::size_t MINALIGN = PMEMPOOL_ALIGN>
class mempool_arena : public arena_base<mempool_arena<BASEARENA>, false, false>
{
public:
@@ -37,7 +37,7 @@ namespace plib {
template <class T>
using base_allocator_type = typename BASEARENA::template allocator_type<T>;
- 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 <typename S, typename T>
+ 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<ct *>(data), gsl::narrow<std::streamsize>(len * sizeof(T)));
+ }
+
+ /// \brief wrapper around osteam write
+ ///
+ template <typename S, typename T>
+ 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<const ct *>(data), gsl::narrow<std::streamsize>(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 <typename T>
void write(const T &val)
{
- m_strm.write(reinterpret_cast<const std::ostream::char_type *>(&val), sizeof(T));
+ ostream_write(m_strm, &val, 1);
}
void write(const pstring &s)
{
- const auto *const sm = reinterpret_cast<const std::ostream::char_type *>(s.c_str());
- const auto sl(static_cast<std::streamsize>(std::char_traits<std::ostream::char_type>::length(sm)));
+ auto *sm = s.c_str();
+ const auto sl(std::char_traits<pstring::mem_t>::length(sm));
write(sl);
- m_strm.write(sm, sl);
+ ostream_write(m_strm, sm, sl);
}
template <typename T>
void write(const std::vector<T> &val)
{
- const auto sz(static_cast<std::streamsize>(val.size()));
+ const auto sz(val.size());
write(sz);
- m_strm.write(reinterpret_cast<const std::ostream::char_type *>(val.data()), sz * gsl::narrow<std::streamsize>(sizeof(T)));
+ ostream_write(m_strm, val.data(), sz);
}
private:
@@ -225,7 +246,7 @@ public:
template <typename T>
void read(T &val)
{
- m_strm.read(reinterpret_cast<std::istream::char_type *>(&val), gsl::narrow<std::streamsize>(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<std::istream::char_type *>(val.data()), gsl::narrow<std::streamsize>(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>;
mutex_type m_lock;
- PALIGNAS_CACHELINE()
T * m_end;
aligned_vector<T> 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 <typename T>
void write(const T &val)
{
- static_assert(sizeof(std::ostream::char_type) == 1, "char_type size must be 1");
- const auto *ptr(reinterpret_cast<const std::ostream::char_type *>(&val));
- m_f.write(ptr, sizeof(T));
+ plib::ostream_write(m_f, &val, 1);
}
template <typename T>
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<matrix_solver_t *>;
using fptype = nl_fptype;
- using arena_type = plib::mempool_arena<plib::aligned_arena>;
+ using arena_type = plib::mempool_arena<plib::aligned_arena, PALIGN_VECTOROPT>;
// 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<solver::matrix_solver_t>;
+
// FIXME: should be created in device space
template <class C>
- host_arena::unique_ptr<solver::matrix_solver_t> 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 &params, std::size_t size)
{
return plib::make_unique<C, host_arena>(nl, name, nets, &params, size);
+ //return nl.make_pool_object<C>(nl, name, nets, &params, size);
}
template <typename FT, int SIZE>
- host_arena::unique_ptr<solver::matrix_solver_t> 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<solver::matrix_solver_GCR_t<FT, SIZE>>(state(), solvername, nets, m_params, size);
#endif
}
- return host_arena::unique_ptr<solver::matrix_solver_t>();
+ return solver_ptr();
}
template <typename FT>
- host_arena::unique_ptr<solver::matrix_solver_t> 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<solver::matrix_solver_direct1_t<FT>, host_arena>(state(), sname, nets, &m_params);
+ //return state().make_pool_object<solver::matrix_solver_direct1_t<FT>>(state(), sname, nets, &m_params);
case 2:
return plib::make_unique<solver::matrix_solver_direct2_t<FT>, host_arena>(state(), sname, nets, &m_params);
+ //return state().make_pool_object<solver::matrix_solver_direct2_t<FT>>(state(), sname, nets, &m_params);
case 3:
return create_solver<FT, 3>(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<solver::matrix_solver_t> 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<solver::matrix_solver_t>;
+ using solver_ptr = host_arena::unique_ptr<solver::matrix_solver_t>;
+
private:
logic_input_t m_fb_step;
logic_output_t m_Q_step;
// FIXME: these should be created in device space
- std::vector<host_arena::unique_ptr<solver::matrix_solver_t>> m_mat_solvers;
+ std::vector<solver_ptr> m_mat_solvers;
std::vector<solver::matrix_solver_t *> m_mat_solvers_all;
std::vector<solver::matrix_solver_t *> m_mat_solvers_timestepping;
solver::solver_parameters_t m_params;
template <typename FT, int SIZE>
- host_arena::unique_ptr<solver::matrix_solver_t> create_solver(std::size_t size,
+ solver_ptr create_solver(std::size_t size,
const pstring &solvername, analog_net_t::list_t &nets);
template <typename FT>
- host_arena::unique_ptr<solver::matrix_solver_t> create_solvers(
+ solver_ptr create_solvers(
const pstring &sname, analog_net_t::list_t &nets);
};