From f27ccb330360d754aa8634c48be935328d0b3f86 Mon Sep 17 00:00:00 2001 From: Couriersud Date: Thu, 29 May 2014 14:03:07 +0000 Subject: [PATCH] Further work on vectorization. Works but not yet finished. --- src/emu/netlist/analog/nld_solver.c | 213 +++++++++++++++++----------- src/emu/netlist/analog/nld_solver.h | 109 +++++++------- src/emu/netlist/nl_base.h | 2 +- src/emu/netlist/plists.h | 16 ++- 4 files changed, 194 insertions(+), 146 deletions(-) diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index d6544d632d4..e0f03c973b0 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -41,7 +41,7 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_analog_net_t::list_t &nets for (int k = 0; k < nets.count(); k++) { - m_nets.add(net_entry(nets[k])); + m_nets.add(nets[k]); } for (int k = 0; k < nets.count(); k++) @@ -80,11 +80,13 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_analog_net_t::list_t &nets netlist_terminal_t *pterm = dynamic_cast(p); // for gauss seidel pterm->m_new_analog_ptr = &pterm->m_otherterm->net().as_analog().m_new_Analog; - +#if 0 if (pterm->m_otherterm->net().isRailNet()) m_nets[k].m_rails.add(pterm); else m_nets[k].m_terms.add(pterm); +#endif + add_term(k, pterm); } NL_VERBOSE_OUT(("Added terminal\n")); break; @@ -139,7 +141,7 @@ ATTR_HOT double netlist_matrix_solver_direct_t::compute_next_ti #else for (int k = 0; k < N(); k++) { - netlist_analog_net_t *n = m_nets[k].m_net; + netlist_analog_net_t *n = m_nets[k]; #endif double DD_n = (n->m_cur_Analog - n->m_last_Analog); @@ -190,7 +192,7 @@ ATTR_HOT void netlist_matrix_solver_t::update_inputs() #if 1 for (int k = 0; k < m_nets.count(); k++) { - netlist_analog_net_t *p= m_nets[k].m_net; + netlist_analog_net_t *p= m_nets[k]; p->m_last_Analog = p->m_cur_Analog; } #else @@ -323,19 +325,51 @@ void netlist_matrix_solver_gauss_seidel_t::log_stats() ATTR_COLD int netlist_matrix_solver_t::get_net_idx(netlist_net_t *net) { for (int k = 0; k < m_nets.count(); k++) - if (m_nets[k].m_net == net) + if (m_nets[k] == net) return k; return -1; } +template +ATTR_COLD void netlist_matrix_solver_direct_t::add_term(int k, netlist_terminal_t *term) +{ + if (term->m_otherterm->net().isRailNet()) + { + //m_nets[k].m_rails.add(pterm); + m_rails[k].add(terms_t(term, -1)); + } + else + { + int ot = get_net_idx(&term->m_otherterm->net()); + if (ot>=0) + { + m_terms[k].add(terms_t(term, ot)); + SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go)); + } + /* Should this be allowed ? */ + else // if (ot<0) + { + m_rails[k].add(terms_t(term, ot)); + netlist().error("found term with missing othernet %s\n", term->name().cstr()); + } + } +} + + template ATTR_COLD void netlist_matrix_solver_direct_t::vsetup(netlist_analog_net_t::list_t &nets) { m_dim = nets.count(); - netlist_matrix_solver_t::setup(nets); - m_terms.clear(); - m_rail_start = 0; + for (int k = 0; k < N(); k++) + { + m_terms[k].clear(); + m_rails[k].clear(); + } + + netlist_matrix_solver_t::setup(nets); + +#if 0 for (int k = 0; k < N(); k++) { const netlist_terminal_t::list_t &terms = m_nets[k].m_terms; @@ -344,31 +378,38 @@ ATTR_COLD void netlist_matrix_solver_direct_t::vsetup(netlist_a int ot = get_net_idx(&terms[i]->m_otherterm->net()); if (ot>=0) { - m_terms.add(terms_t(terms[i], k, ot)); + m_terms[k].add(terms_t(terms[i], ot)); SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go)); } } } - m_rail_start = m_terms.count(); + + /* Should this be allowed ? */ for (int k = 0; k < N(); k++) { const netlist_terminal_t::list_t &terms = m_nets[k].m_terms; - const netlist_terminal_t::list_t &rails = m_nets[k].m_rails; for (int i = 0; i < terms.count(); i++) { int ot = get_net_idx(&terms[i]->m_otherterm->net()); if (ot<0) { - m_terms.add(terms_t(terms[i], k, ot)); + m_rails[k].add(terms_t(terms[i], ot)); netlist().warning("found term with missing othernet %s\n", terms[i]->name().cstr()); } } + } + + + for (int k = 0; k < N(); k++) + { + const netlist_terminal_t::list_t &rails = m_nets[k].m_rails; for (int i = 0; i < rails.count(); i++) { - m_terms.add(terms_t(rails[i], k, -1)); + m_rails[k].add(terms_t(rails[i], -1)); SOLVER_VERBOSE_OUT(("Net %d Rail %s %f %f\n", k, rails[i]->name().cstr(), rails[i]->m_gt, rails[i]->m_go)); } } +#endif } template @@ -378,43 +419,35 @@ ATTR_HOT void netlist_matrix_solver_direct_t::build_LE() for (int i=0; i < _storage_N; i++) m_A[k][i] = 0.0; - for (int k=0; k < _storage_N; k++) - m_RHS[k] = 0.0; -#if 0 - - for (int i = 0; i < m_term_num; i++) + for (int k = 0; k < N(); k++) { - terms_t &t = m_terms[i]; - m_RHS[t.m_net_this] += t.m_term->m_Idr; - m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt; - if (t.m_net_other >= 0) + double rhsk = 0.0; + double akk = 0.0; + const int terms_count = m_terms[k].count(); + const terms_t *terms = m_terms[k]; + + for (int i = 0; i < terms_count; i++) { - //m_A[t.net_other][t.net_other] += t.term->m_otherterm->m_gt; - m_A[t.m_net_this][t.m_net_other] += -t.m_term->m_go; - //m_A[t.net_other][t.net_this] += -t.term->m_otherterm->m_go; + //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go); + + rhsk = rhsk + terms[i].m_term->m_Idr; + akk = akk + terms[i].m_term->m_gt; + m_A[k][terms[i].m_net_other] += -terms[i].m_term->m_go; } - else - m_RHS[t.m_net_this] += t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog(); - } -#else - for (int i = 0; i < m_rail_start; i++) - { - const terms_t &t = m_terms[i]; - //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go); - m_RHS[t.m_net_this] += t.m_term->m_Idr; - m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt; - m_A[t.m_net_this][t.m_net_other] += -t.m_term->m_go; - } - for (int i = m_rail_start; i < m_terms.count(); i++) - { - const terms_t &t = m_terms[i]; + const int rails_count = m_rails[k].count(); + const terms_t *rails = m_rails[k]; - m_RHS[t.m_net_this] += t.m_term->m_Idr; - m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt; - m_RHS[t.m_net_this] += t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog(); - } -#endif + for (int i = 0; i < rails_count; i++) + { + const terms_t t = rails[i]; + + rhsk = rhsk + t.m_term->m_Idr + t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog(); + akk = akk + t.m_term->m_gt; + } + m_RHS[k] = rhsk; + m_A[k][k] += akk; + } } template @@ -504,7 +537,7 @@ ATTR_HOT double netlist_matrix_solver_direct_t::delta( double cerr2 = 0; for (int i = 0; i < this->N(); i++) { - const double e = (V[i] - this->m_nets[i].m_net->m_cur_Analog); + const double e = (V[i] - this->m_nets[i]->m_cur_Analog); const double e2 = (m_RHS[i] - this->m_last_RHS[i]); cerr = (fabs(e) > cerr ? fabs(e) : cerr); cerr2 = (fabs(e2) > cerr2 ? fabs(e2) : cerr2); @@ -519,7 +552,7 @@ ATTR_HOT void netlist_matrix_solver_direct_t::store( { for (int i = 0; i < this->N(); i++) { - this->m_nets[i].m_net->m_cur_Analog = this->m_nets[i].m_net->m_new_Analog = V[i]; + this->m_nets[i]->m_cur_Analog = this->m_nets[i]->m_new_Analog = V[i]; } if (store_RHS) { @@ -569,7 +602,7 @@ ATTR_HOT int netlist_matrix_solver_direct_t::vsolve_non_dynamic ATTR_HOT int netlist_matrix_solver_direct1_t::vsolve_non_dynamic() { - netlist_analog_net_t *net = m_nets[0].m_net; + netlist_analog_net_t *net = m_nets[0]; this->build_LE(); //NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]); @@ -646,7 +679,7 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t::vsolve_non_d for (int k = 0; k < iN; k++) { - new_v[k] = this->m_nets[k].m_net->m_cur_Analog; + new_v[k] = this->m_nets[k]->m_cur_Analog; } do { resched = false; @@ -708,7 +741,7 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t::vsolve_non_d for (int k = 0; k < iN; k++) { - this->m_nets[k].m_net->m_new_Analog = this->m_nets[k].m_net->m_cur_Analog; + this->m_nets[k]->m_new_Analog = this->m_nets[k]->m_cur_Analog; } for (int k = 0; k < iN; k++) @@ -717,25 +750,26 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t::vsolve_non_d double gabs_t = 0.0; double RHS_t = 0.0; - //const netlist_analog_net_t &net = *this->m_nets[k]; - const netlist_terminal_t::list_t &terms = this->m_nets[k].m_terms; - const netlist_terminal_t::list_t &rails = this->m_nets[k].m_rails; + const typename netlist_matrix_solver_direct_t::xlist_t &terms = this->m_terms[k]; + const typename netlist_matrix_solver_direct_t::xlist_t &rails = this->m_rails[k]; const int term_count = terms.count(); const int rail_count = rails.count(); for (int i = 0; i < rail_count; i++) { - gtot_t += rails[i]->m_gt; - gabs_t += fabs(rails[i]->m_go); - RHS_t += rails[i]->m_Idr; - RHS_t += rails[i]->m_go * rails[i]->m_otherterm->net().as_analog().Q_Analog(); + const netlist_terminal_t *rail = rails[i].m_term; + gtot_t += rail->m_gt; + gabs_t += fabs(rail->m_go); + RHS_t += rail->m_Idr; + RHS_t += rail->m_go * rail->m_otherterm->net().as_analog().Q_Analog(); } for (int i = 0; i < term_count; i++) { - gtot_t += terms[i]->m_gt; - gabs_t += fabs(terms[i]->m_go); - RHS_t += terms[i]->m_Idr; + const netlist_terminal_t *term = terms[i].m_term; + gtot_t += term->m_gt; + gabs_t += fabs(term->m_go); + RHS_t += term->m_Idr; } gabs_t *= 1.0; @@ -760,13 +794,13 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t::vsolve_non_d for (int k = 0; k < iN; k++) { - netlist_analog_net_t & RESTRICT net = *this->m_nets[k].m_net; - const netlist_terminal_t::list_t &terms = this->m_nets[k].m_terms; + netlist_analog_net_t & RESTRICT net = *this->m_nets[k]; + const typename netlist_matrix_solver_direct_t::xlist_t &terms = this->m_terms[k]; const int term_count = terms.count(); double Idrive = 0; for (int i = 0; i < term_count; i++) - Idrive += terms[i]->m_go * *(terms[i]->m_new_analog_ptr); + Idrive += terms[i].m_term->m_go * *(terms[i].m_term->m_new_analog_ptr); //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]); const double new_val = net.m_new_Analog * one_m_w[k] + (Idrive + RHS[k]) * w[k]; @@ -796,7 +830,7 @@ ATTR_HOT int netlist_matrix_solver_gauss_seidel_t::vsolve_non_d this->m_calculations++; for (int k = 0; k < this->N(); k++) - this->m_nets[k].m_net->m_cur_Analog = this->m_nets[k].m_net->m_new_Analog; + this->m_nets[k]->m_cur_Analog = this->m_nets[k]->m_new_Analog; return resched_cnt; } @@ -906,11 +940,29 @@ NETLIB_UPDATE(solver) } } +template +netlist_matrix_solver_t * NETLIB_NAME(solver)::create_solver(const int gs_threshold, const bool use_specific) +{ + if (use_specific && m_N == 1) + return new netlist_matrix_solver_direct1_t(); + else if (use_specific && m_N == 2) + return new netlist_matrix_solver_direct2_t(); + else + { + if (_storage_N >= gs_threshold) + return new netlist_matrix_solver_gauss_seidel_t(); + else + return new netlist_matrix_solver_direct_t(); + } +} ATTR_COLD void NETLIB_NAME(solver)::post_start() { netlist_analog_net_t::list_t groups[100]; int cur_group = -1; + // FIXME: Turn into parameters ... + const int gs_threshold = 5; + const bool use_specific = true; m_params.m_accuracy = m_accuracy.Value(); m_params.m_gs_loops = m_gs_loops.Value(); @@ -956,53 +1008,42 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() switch (net_count) { -#if 1 case 1: - ms = new netlist_matrix_solver_direct1_t(); + ms = create_solver<1,1>(gs_threshold, use_specific); break; case 2: - ms = new netlist_matrix_solver_direct2_t(); + ms = create_solver<2,2>(gs_threshold, use_specific); break; case 3: - ms = new netlist_matrix_solver_direct_t<3,3>(); - //ms = new netlist_matrix_solver_gauss_seidel_t<3,3>(); + ms = create_solver<3,3>(gs_threshold, use_specific); break; case 4: - ms = new netlist_matrix_solver_direct_t<4,4>(); - //ms = new netlist_matrix_solver_gauss_seidel_t<4,4>(); + ms = create_solver<4,4>(gs_threshold, use_specific); break; case 5: - ms = new netlist_matrix_solver_direct_t<5,5>(); - //ms = new netlist_matrix_solver_gauss_seidel_t<5,5>(); + ms = create_solver<5,5>(gs_threshold, use_specific); break; case 6: - ms = new netlist_matrix_solver_direct_t<6,6>(); - //ms = new netlist_matrix_solver_gauss_seidel_t<6,6>(); + ms = create_solver<6,6>(gs_threshold, use_specific); break; case 7: - //ms = new netlist_matrix_solver_direct_t<6,6>(); - ms = new netlist_matrix_solver_gauss_seidel_t<7,7>(); + ms = create_solver<7,7>(gs_threshold, use_specific); break; case 8: - //ms = new netlist_matrix_solver_direct_t<6,6>(); - ms = new netlist_matrix_solver_gauss_seidel_t<8,8>(); + ms = create_solver<8,8>(gs_threshold, use_specific); break; -#endif default: if (net_count <= 16) { - //ms = new netlist_matrix_solver_direct_t<0,16>(); - ms = new netlist_matrix_solver_gauss_seidel_t<0,16>(); + ms = create_solver<0,16>(gs_threshold, use_specific); } else if (net_count <= 32) { - //ms = new netlist_matrix_solver_direct_t<0,16>(); - ms = new netlist_matrix_solver_gauss_seidel_t<0,32>(); + ms = create_solver<0,32>(gs_threshold, use_specific); } else if (net_count <= 64) { - //ms = new netlist_matrix_solver_direct_t<0,16>(); - ms = new netlist_matrix_solver_gauss_seidel_t<0,64>(); + ms = create_solver<0,64>(gs_threshold, use_specific); } else { diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index 8533f3aa075..99b044d2763 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -9,6 +9,9 @@ #include "../nl_setup.h" #include "../nl_base.h" +//#define ATTR_ALIGNED(N) __attribute__((aligned(N))) +#define ATTR_ALIGNED(N) ATTR_ALIGN + // ---------------------------------------------------------------------------------------- // Macros // ---------------------------------------------------------------------------------------- @@ -37,7 +40,7 @@ struct netlist_solver_parameters_t netlist_time m_nt_sync_delay; }; -class netlist_matrix_solver_t : public netlist_device_t +class ATTR_ALIGNED(64) netlist_matrix_solver_t : public netlist_device_t { public: typedef plinearlist_t list_t; @@ -67,40 +70,15 @@ public: protected: - class net_entry - { - public: - net_entry(netlist_analog_net_t *net) : m_net(net) {} - net_entry() : m_net(NULL) {} - - net_entry(const net_entry &rhs) - { - m_net = rhs.m_net; - m_terms = rhs.m_terms; - m_rails = rhs.m_rails; - } - - net_entry &operator=(const net_entry &rhs) - { - m_net = rhs.m_net; - m_terms = rhs.m_terms; - m_rails = rhs.m_rails; - return *this; - } - - netlist_analog_net_t * RESTRICT m_net; - netlist_terminal_t::list_t m_terms; - netlist_terminal_t::list_t m_rails; - }; - ATTR_COLD void setup(netlist_analog_net_t::list_t &nets); // return true if a reschedule is needed ... ATTR_HOT virtual int vsolve_non_dynamic() = 0; + ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term) = 0; int m_calculations; - plinearlist_t m_nets; + plinearlist_t m_nets; plinearlist_t m_inps; private: @@ -126,14 +104,13 @@ private: }; template -class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t +class ATTR_ALIGNED(64) netlist_matrix_solver_direct_t: public netlist_matrix_solver_t { public: netlist_matrix_solver_direct_t() : netlist_matrix_solver_t() , m_dim(0) - , m_rail_start(0) {} virtual ~netlist_matrix_solver_direct_t() {} @@ -144,6 +121,8 @@ public: ATTR_HOT inline const int N() const { if (m_N == 0) return m_dim; else return m_N; } protected: + ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term); + ATTR_HOT virtual int vsolve_non_dynamic(); ATTR_HOT int solve_non_dynamic(); ATTR_HOT inline void build_LE(); @@ -154,31 +133,35 @@ protected: ATTR_HOT virtual double compute_next_timestep(const double); - double m_A[_storage_N][_storage_N]; - double m_RHS[_storage_N]; - double m_last_RHS[_storage_N]; // right hand side - contains currents + ATTR_ALIGNED(64) double m_A[_storage_N][_storage_N]; + ATTR_ALIGNED(64) double m_RHS[_storage_N]; + ATTR_ALIGNED(64) double m_last_RHS[_storage_N]; // right hand side - contains currents - struct terms_t{ + struct ATTR_ALIGNED(64) terms_t{ - terms_t(netlist_terminal_t *term, int net_this, int net_other) - : m_term(term), m_net_this(net_this), m_net_other(net_other) + terms_t(netlist_terminal_t *term, int net_other) + : m_term(term), m_net_other(net_other) {} terms_t() - : m_term(NULL), m_net_this(-1), m_net_other(-1) + : m_term(NULL), m_net_other(-1) {} - netlist_terminal_t * RESTRICT m_term; - int m_net_this; + ATTR_ALIGNED(64) netlist_terminal_t ATTR_ALIGNED(64) * RESTRICT m_term; int m_net_other; }; + typedef plinearlist_t xlist_t; + xlist_t m_terms[_storage_N]; + xlist_t m_rails[_storage_N]; + plinearlist_t xx[_storage_N]; + +private: + int m_dim; - int m_rail_start; - plinearlist_t m_terms; }; template -class netlist_matrix_solver_gauss_seidel_t: public netlist_matrix_solver_direct_t +class ATTR_ALIGNED(64) netlist_matrix_solver_gauss_seidel_t: public netlist_matrix_solver_direct_t { public: @@ -201,22 +184,39 @@ private: }; -class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1> +class ATTR_ALIGNED(64) netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1> { protected: ATTR_HOT int vsolve_non_dynamic(); private: }; -class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2> +class ATTR_ALIGNED(64) netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2> { protected: ATTR_HOT int vsolve_non_dynamic(); private: }; -NETLIB_DEVICE_WITH_PARAMS(solver, - typedef netlist_core_device_t::list_t dev_list_t; +class ATTR_ALIGNED(64) NETLIB_NAME(solver) : public netlist_device_t +{ +public: + NETLIB_NAME(solver)() + : netlist_device_t() { } + + ATTR_COLD virtual ~NETLIB_NAME(solver)(); + + ATTR_COLD void post_start(); + + ATTR_HOT inline double gmin() { return m_gmin.Value(); } + +protected: + ATTR_HOT void update(); + ATTR_HOT void start(); + ATTR_HOT void reset(); + ATTR_HOT void update_param(); + + //typedef netlist_core_device_t::list_t dev_list_t; netlist_ttl_input_t m_fb_step; netlist_ttl_output_t m_Q_step; @@ -234,17 +234,14 @@ NETLIB_DEVICE_WITH_PARAMS(solver, netlist_param_int_t m_parallel; netlist_matrix_solver_t::list_t m_mat_solvers; -public: - - ATTR_COLD virtual ~NETLIB_NAME(solver)(); - - ATTR_COLD void post_start(); - - ATTR_HOT inline double gmin() { return m_gmin.Value(); } - private: - netlist_solver_parameters_t m_params; -); + + netlist_solver_parameters_t m_params; + + template + netlist_matrix_solver_t *create_solver(int gs_threshold, bool use_specific); +}; + #endif /* NLD_SOLVER_H_ */ diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index 0d66d5a6985..5dbcc5f6200 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -424,7 +424,7 @@ private: NETLIST_SAVE_TYPE(netlist_core_terminal_t::state_e, DT_INT); -class netlist_terminal_t : public netlist_core_terminal_t +class ATTR_ALIGN netlist_terminal_t : public netlist_core_terminal_t { NETLIST_PREVENT_COPYING(netlist_terminal_t) public: diff --git a/src/emu/netlist/plists.h b/src/emu/netlist/plists.h index 9d691ce3cda..e309c65b1a1 100644 --- a/src/emu/netlist/plists.h +++ b/src/emu/netlist/plists.h @@ -64,6 +64,19 @@ public: m_list = NULL; } + ATTR_HOT inline operator _ListClass * () { return m_list; } + ATTR_HOT inline operator const _ListClass * const () { return m_list; } + + /* using the [] operator will not allow gcc to vectorize code because + * basically a pointer is returned. + * array works around this. + */ + + ATTR_HOT inline _ListClass *array() { return m_list; } + + ATTR_HOT inline _ListClass& operator[](const int index) { return m_list[index]; } + ATTR_HOT inline const _ListClass& operator[](const int index) const { return m_list[index]; } + ATTR_HOT inline void add(const _ListClass &elem) { if (m_count >= m_num_elements){ @@ -140,9 +153,6 @@ public: clear(); } - ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index]; } - ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index]; } - private: ATTR_HOT inline void resize(const int new_size) {