Previous 199869 Revisions Next

r30980 Sunday 15th June, 2014 at 15:06:23 UTC by Couriersud
netlist:
- Removed m_new_Analog
- Did some tests using linear prediction. This is not used since the savings are about the same size as the effort.
[src/emu/netlist]nl_base.c nl_base.h
[src/emu/netlist/analog]nld_solver.c nld_solver.h

trunk/src/emu/netlist/analog/nld_solver.c
r30979r30980
1717#define VECTALT 1
1818#define USE_GABS 0
1919#define USE_MATRIX_GS 0
20//#define SORP 1.059
2021#define SORP 1.059
22// savings are eaten up by effort
23#define USE_LINEAR_PREDICTION (0)
2124
2225#define SOLVER_VERBOSE_OUT(x) do {} while (0)
2326//#define SOLVER_VERBOSE_OUT(x) printf x
r30979r30980
103106// ----------------------------------------------------------------------------------------
104107
105108ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t()
106: m_calculations(0)
109: m_calculations(0), m_cur_ts(0)
107110{
108111}
109112
r30979r30980
202205netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(int size)
203206: netlist_matrix_solver_t()
204207, m_dim(size)
208, m_lp_fact(0)
205209{
206210    m_terms = new terms_t *[N()];
207211    m_rails_temp = new terms_t[N()];
r30979r30980
230234}
231235
232236template <int m_N, int _storage_N>
233ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep(const double hn)
237ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
234238{
235239    double new_solver_timestep = m_params.m_max_timestep;
236240
r30979r30980
249253        {
250254            netlist_analog_net_t *n = m_nets[k];
251255#endif
252            double DD_n = (n->m_cur_Analog - n->m_last_Analog);
256            const double DD_n = (n->m_cur_Analog - m_last_V[k]);
257            const double hn = current_timestep();
253258
254259            double DD2 = (DD_n / hn - n->m_DD_n_m_1 / n->m_h_n_m_1) / (hn + n->m_h_n_m_1);
255260            double new_net_timestep;
r30979r30980
276281{
277282    // avoid recursive calls. Inputs are updated outside this call
278283    for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
279        if ((*p)->m_proxied_net->m_last_Analog != (*p)->m_proxied_net->m_cur_Analog)
280            (*p)->set_Q((*p)->m_proxied_net->m_cur_Analog);
284        (*p)->set_Q((*p)->m_proxied_net->m_cur_Analog);
281285
282286    for (int k = 0; k < m_nets.count(); k++)
283287    {
r30979r30980
337341      m_step_devices[k]->step_time(dd);
338342}
339343
344template<class C >
345void netlist_matrix_solver_t::solve_base(C *p)
346{
347    if (is_dynamic())
348    {
349        int this_resched;
350        int newton_loops = 0;
351        do
352        {
353            update_dynamic();
354            // Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
355            this_resched = p->vsolve_non_dynamic();
356            newton_loops++;
357        } while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
358
359        // reschedule ....
360        if (this_resched > 1 && !m_Q_sync.net().is_queued())
361        {
362            netlist().warning("NEWTON_LOOPS exceeded ... reschedule");
363            m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay);
364        }
365    }
366    else
367    {
368        p->vsolve_non_dynamic();
369    }
370}
371
340372ATTR_HOT double netlist_matrix_solver_t::solve()
341373{
342374
r30979r30980
347379   if (delta < netlist_time::from_nsec(1))
348380       return -1.0;
349381
350   NL_VERBOSE_OUT(("Step!\n"));
351382   /* update all terminals for new time step */
352383   m_last_step = now;
384   m_cur_ts = delta.as_double();
385
353386   step(delta);
354387
355   if (is_dynamic())
356   {
357      int this_resched;
358      int newton_loops = 0;
359      do
360      {
361            update_dynamic();
362            // Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
363            this_resched = vsolve_non_dynamic();
364            newton_loops++;
365      } while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
388   const double next_time_step = vsolve();
366389
367      // reschedule ....
368      if (this_resched > 1 && !m_Q_sync.net().is_queued())
369      {
370            netlist().warning("NEWTON_LOOPS exceeded ... reschedule");
371           m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay);
372           return 1.0;
373      }
374   }
375   else
376   {
377      vsolve_non_dynamic();
378   }
379   const double next_time_step = compute_next_timestep(delta.as_double());
380390    update_inputs();
381391   return next_time_step;
382392}
r30979r30980
384394template <int m_N, int _storage_N>
385395void netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::log_stats()
386396{
387#if 0
397#if 1
388398    printf("==============================================\n");
389399    printf("Solver %s\n", this->name().cstr());
390400    printf("       ==> %d nets\n", this->N()); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
r30979r30980
532542                akk = akk + gt[i];
533543            }
534544#else
535            const netlist_terminal_t * const * terms = this->m_terms[k]->terms();
536545            m_terms[k]->ops()->sum2(Idr, gt, rhsk, akk);
537546#endif
538547            double * const * RESTRICT other_cur_analog = m_terms[k]->other_curanalog();
r30979r30980
684693{
685694   for (int i = 0; i < this->N(); i++)
686695   {
687      this->m_nets[i]->m_cur_Analog = this->m_nets[i]->m_new_Analog = V[i];
696      this->m_nets[i]->m_cur_Analog = V[i];
688697   }
689698   if (store_RHS)
690699   {
r30979r30980
696705}
697706
698707template <int m_N, int _storage_N>
708ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve()
709{
710    solve_base<netlist_matrix_solver_direct_t>(this);
711    return this->compute_next_timestep();
712}
713
714
715template <int m_N, int _storage_N>
699716ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic()
700717{
701718    double new_v[_storage_N] = { 0.0 };
r30979r30980
719736}
720737
721738template <int m_N, int _storage_N>
722ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic()
739ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic()
723740{
724741   this->build_LE();
725742
r30979r30980
731748// netlist_matrix_solver - Direct1
732749// ----------------------------------------------------------------------------------------
733750
734ATTR_HOT int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
751ATTR_HOT double netlist_matrix_solver_direct1_t::vsolve()
735752{
753    solve_base<netlist_matrix_solver_direct1_t>(this);
754    return this->compute_next_timestep();
755}
736756
757ATTR_HOT inline int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
758{
759
737760    netlist_analog_net_t *net = m_nets[0];
738761   this->build_LE();
739762   //NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]);
r30979r30980
743766   double e = (new_val - net->m_cur_Analog);
744767   double cerr = fabs(e);
745768
746   net->m_cur_Analog = net->m_new_Analog = new_val;
769   net->m_cur_Analog = new_val;
747770
748771   if (is_dynamic() && (cerr  > m_params.m_accuracy))
749772   {
r30979r30980
760783// netlist_matrix_solver - Direct2
761784// ----------------------------------------------------------------------------------------
762785
763ATTR_HOT int netlist_matrix_solver_direct2_t::vsolve_non_dynamic()
786ATTR_HOT double netlist_matrix_solver_direct2_t::vsolve()
764787{
788    solve_base<netlist_matrix_solver_direct2_t>(this);
789    return this->compute_next_timestep();
790}
765791
792ATTR_HOT inline int netlist_matrix_solver_direct2_t::vsolve_non_dynamic()
793{
794
766795   build_LE();
767796
768797   const double a = m_A[0][0];
r30979r30980
776805
777806   if (is_dynamic())
778807   {
779      double err = delta(new_val);
808      double err = this->delta(new_val);
780809      store(new_val, true);
781810      if (err > m_params.m_accuracy )
782811         return 2;
r30979r30980
792821// ----------------------------------------------------------------------------------------
793822
794823template <int m_N, int _storage_N>
795ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_dynamic()
824ATTR_HOT double netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve()
796825{
826    /*
827     * enable linear prediction on first newton pass
828     */
829
830    if (USE_LINEAR_PREDICTION)
831        for (int k = 0; k < this->N(); k++)
832        {
833            this->m_last_V[k] = this->m_nets[k]->m_cur_Analog;
834            this->m_nets[k]->m_cur_Analog = this->m_nets[k]->m_cur_Analog + this->m_Vdelta[k] * this->current_timestep() * m_lp_fact;
835        }
836    else
837        for (int k = 0; k < this->N(); k++)
838        {
839            this->m_last_V[k] = this->m_nets[k]->m_cur_Analog;
840        }
841
842    solve_base(this);
843
844    if (USE_LINEAR_PREDICTION)
845    {
846        double sq = 0;
847        double sqo = 0;
848        for (int k = 0; k < this->N(); k++)
849        {
850            netlist_analog_net_t *n = this->m_nets[k];
851            double nv = (n->m_cur_Analog - this->m_last_V[k]) / this->current_timestep();
852            sq += nv * nv;
853            sqo += this->m_Vdelta[k] * this->m_Vdelta[k];
854            this->m_Vdelta[k] = nv;
855        }
856        if (sqo > 1e-90)
857            m_lp_fact = sqrt(sq/sqo);
858        else
859            m_lp_fact = 0.0;
860        if (m_lp_fact > 2.0)
861            m_lp_fact = 2.0;
862        //printf("fact %f\n", fact);
863    }
864
865
866    return this->compute_next_timestep();
867}
868
869template <int m_N, int _storage_N>
870ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_dynamic()
871{
797872    /* The matrix based code looks a lot nicer but actually is 30% slower than
798873     * the optimized code which works directly on the data structures.
799874     * Need something like that for gaussian elimination as well.
800875     */
801876
802877#if USE_MATRIX_GS
878    static double ws = 1.0;
803879    ATTR_ALIGN double new_v[_storage_N] = { 0.0 };
804880    const int iN = this->N();
805881
r30979r30980
809885
810886    this->build_LE();
811887
812    for (int k = 0; k < iN; k++)
813888    {
814        new_v[k] = this->m_nets[k]->m_cur_Analog;
889        double frob;
890        frob = 0;
891        for (int k = 0; k < iN; k++)
892        {
893            new_v[k] = this->m_nets[k]->m_cur_Analog;
894            for (int i = 0; i < iN; i++)
895            {
896                frob += this->m_A[k][i] * this->m_A[k][i];
897            }
898
899        }
900        double frobA = sqrt(frob /(iN));
901        if (1 &&frobA < 1.0)
902            //ws = 2.0 / (1.0 + sqrt(1.0-frobA));
903            ws = 2.0 / (2.0 - frobA);
904        else
905            ws = 1.0;
906        ws = 0.9;
815907    }
816908
817909    // Frobenius norm for (D-L)^(-1)U
818    double frobU;
819    double frobL;
820    double frob;
821    double norm;
910    //double frobU;
911    //double frobL;
912    //double norm;
822913    do {
823914        resched = false;
824915        double cerr = 0.0;
825        frobU = 0;
826        frobL = 0;
827        frob = 0;
828        norm = 0;
916        //frobU = 0;
917        //frobL = 0;
918        //norm = 0;
829919
830920        for (int k = 0; k < iN; k++)
831921        {
832922            double Idrive = 0;
833            double norm_t = 0;
923            //double norm_t = 0;
834924            // Reduction loops need -ffast-math
835925            for (int i = 0; i < iN; i++)
836926                Idrive += this->m_A[k][i] * new_v[i];
837927
838928            for (int i = 0; i < iN; i++)
839929            {
840                if (i < k) frobL += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] /this-> m_A[k][k];
841                if (i > k) frobU += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] / this->m_A[k][k];
842                frob += this->m_A[k][i] * this->m_A[k][i];
843                norm_t += fabs(this->m_A[k][i]);
930                //if (i < k) frobL += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] /this-> m_A[k][k];
931                //if (i > k) frobU += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] / this->m_A[k][k];
932                //norm_t += fabs(this->m_A[k][i]);
844933            }
845934
846            if (norm_t > norm) norm = norm_t;
847            const double new_val = (this->m_RHS[k] - Idrive + this->m_A[k][k] * new_v[k]) / this->m_A[k][k];
935            //if (norm_t > norm) norm = norm_t;
936            const double new_val = (1.0-ws) * new_v[k] + ws * (this->m_RHS[k] - Idrive + this->m_A[k][k] * new_v[k]) / this->m_A[k][k];
848937
849938            const double e = fabs(new_val - new_v[k]);
850939            cerr = (e > cerr ? e : cerr);
r30979r30980
856945            resched = true;
857946        }
858947        resched_cnt++;
948        //ATTR_UNUSED double frobUL = sqrt((frobU + frobL) / (double) (iN) / (double) (iN));
859949    } while (resched && (resched_cnt < this->m_params.m_gs_loops));
860    printf("Frobenius %f %f %f %f %f\n", sqrt(frobU), sqrt(frobL), sqrt(frobU * frobL + (double) iN), sqrt(frob), norm);
861    frobU = sqrt(frobU);
862    frobL = sqrt(frobL);
863    printf("Estimate Frobenius %f\n", 1.0 - (1.0 - frobU -frobL) / (1.0 - frobL) ); //        printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
950    //printf("Frobenius %f %f %f %f %f\n", sqrt(frobU), sqrt(frobL), frobUL, frobA, norm);
951    //printf("Omega Estimate1 %f %f\n", 2.0 / (1.0 + sqrt(1-frobUL)), 2.0 / (1.0 + sqrt(1-frobA)) ); //        printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
952    //printf("Omega Estimate2 %f %f\n", 2.0 / (2.0 - frobUL), 2.0 / (2.0 - frobA) ); //        printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
864953
865954
866955    this->store(new_v, false);
r30979r30980
884973    const int iN = this->N();
885974   bool resched = false;
886975   int  resched_cnt = 0;
887   /* some minor SOR helps on typical netlist matrices */
888976
889977   /* ideally, we could get an estimate for the spectral radius of
890978    * Inv(D - L) * U
r30979r30980
903991
904992    for (int k = 0; k < iN; k++)
905993    {
906        new_V[k] = this->m_nets[k]->m_new_Analog = this->m_nets[k]->m_cur_Analog;
994        new_V[k] = this->m_nets[k]->m_cur_Analog;
907995    }
908
909996   for (int k = 0; k < iN; k++)
910997   {
911998      double gtot_t = 0.0;
r30979r30980
9581045
9591046   do {
9601047      resched = false;
961      double cerr = 0.0;
1048      //double cerr = 0.0;
9621049
9631050      for (int k = 0; k < iN; k++)
9641051      {
9651052            const int * RESTRICT net_other = this->m_terms[k]->net_other();
9661053         const int railstart = this->m_terms[k]->m_railstart;
9671054            const double * RESTRICT go = this->m_terms[k]->go();
968            // -msse2 -msse3 -msse4.1 -msse4.2 -mfpmath=sse -ftree-vectorizer-verbose=3 -fprefetch-loop-arrays -ffast-math
9691055
970         double Idrive;
971
972            Idrive = 0.0;
1056         double Idrive = 0.0;
9731057            for (int i = 0; i < railstart; i++)
9741058                Idrive = Idrive + go[i] * new_V[net_other[i]];
9751059
9761060            //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]);
9771061         const double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k];
9781062
979         const double e = fabs(new_val - new_V[k]);
980         cerr = (e > cerr ? e : cerr);
1063         resched = resched || (fabs(new_val - new_V[k]) > this->m_params.m_accuracy);
1064            new_V[k] = new_val;
1065      }
9811066
982         new_V[k] = new_val;
983      }
984      if (cerr > this->m_params.m_accuracy)
985      {
986         resched = true;
987      }
9881067      resched_cnt++;
9891068   } while (resched && (resched_cnt < this->m_params.m_gs_loops));
9901069
9911070    for (int k = 0; k < iN; k++)
992        this->m_nets[k]->m_new_Analog = this->m_nets[k]->m_cur_Analog = new_V[k];
1071        this->m_nets[k]->m_cur_Analog = new_V[k];
9931072
9941073   this->m_gs_total += resched_cnt;
9951074
r30979r30980
10241103   register_param("FREQ", m_freq, 48000.0);
10251104
10261105   register_param("ACCURACY", m_accuracy, 1e-7);
1027   register_param("GS_LOOPS", m_gs_loops, 9);              // Gauss-Seidel loops
1028    //register_param("GS_THRESHOLD", m_gs_threshold, 99);          // below this value, gaussian elimination is used
1106    register_param("GS_LOOPS", m_gs_loops, 9);              // Gauss-Seidel loops
10291107    register_param("GS_THRESHOLD", m_gs_threshold, 5);          // below this value, gaussian elimination is used
10301108    register_param("NR_LOOPS", m_nr_loops, 25);             // Newton-Raphson loops
10311109   register_param("PARALLEL", m_parallel, 0);
r30979r30980
11801258
11811259      switch (net_count)
11821260      {
1183#if 1
11841261         case 1:
11851262            ms = create_solver<1,1>(1, gs_threshold, use_specific);
11861263            break;
r30979r30980
12081285            case 12:
12091286                ms = create_solver<12,12>(12, gs_threshold, use_specific);
12101287                break;
1211#endif
12121288            default:
12131289            if (net_count <= 16)
12141290            {
trunk/src/emu/netlist/analog/nld_solver.h
r30979r30980
196196
197197    ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0;
198198
199    template<class C>
200    void solve_base(C *p);
201
199202   ATTR_HOT double solve();
200203
201204   ATTR_HOT inline bool is_dynamic() { return m_dynamic_devices.count() > 0; }
r30979r30980
216219protected:
217220
218221    ATTR_COLD void setup(netlist_analog_net_t::list_t &nets);
222    ATTR_HOT void update_dynamic();
219223
220    // return true if a reschedule is needed ...
221    ATTR_HOT virtual int vsolve_non_dynamic() = 0;
224    // should return next time step
225    ATTR_HOT virtual double vsolve() = 0;
222226
223227    ATTR_COLD virtual void  add_term(int net_idx, netlist_terminal_t *term) = 0;
224228
r30979r30980
227231
228232    int m_calculations;
229233
234    ATTR_HOT inline const double current_timestep() { return m_cur_ts; }
230235private:
231236
232237    netlist_time m_last_step;
238    double m_cur_ts;
233239    dev_list_t m_step_devices;
234240    dev_list_t m_dynamic_devices;
235241
r30979r30980
238244
239245    ATTR_HOT void step(const netlist_time delta);
240246
241    /* bring the whole system to the current time
242     * Don't schedule a new calculation time. The recalculation has to be
243     * triggered by the caller after the netlist element was changed.
244     */
245    ATTR_HOT virtual double compute_next_timestep(const double) = 0;
246
247247    ATTR_HOT void update_inputs();
248    ATTR_HOT void update_dynamic();
249248
250249};
251250
r30979r30980
263262
264263   ATTR_HOT inline const int N() const { if (m_N == 0) return m_dim; else return m_N; }
265264
265    ATTR_HOT inline int vsolve_non_dynamic();
266
266267protected:
267268    ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term);
268269
269    ATTR_HOT virtual int vsolve_non_dynamic();
270    ATTR_HOT virtual double vsolve();
271
270272    ATTR_HOT int solve_non_dynamic();
271273   ATTR_HOT void build_LE();
272274   ATTR_HOT void gauss_LE(double (* RESTRICT x));
273275   ATTR_HOT double delta(const double (* RESTRICT V));
274276   ATTR_HOT void store(const double (* RESTRICT V), const bool store_RHS);
275277
276    ATTR_HOT virtual double compute_next_timestep(const double);
278    /* bring the whole system to the current time
279     * Don't schedule a new calculation time. The recalculation has to be
280     * triggered by the caller after the netlist element was changed.
281     */
282    ATTR_HOT double compute_next_timestep();
277283
278284    double m_A[_storage_N][((_storage_N + 7) / 8) * 8];
279285    double m_RHS[_storage_N];
280286    double m_last_RHS[_storage_N]; // right hand side - contains currents
287    double m_Vdelta[_storage_N];
288    double m_last_V[_storage_N];
281289
282290    terms_t **m_terms;
283291
r30979r30980
287295    vector_ops_t *m_row_ops[_storage_N + 1];
288296
289297   int m_dim;
298   double m_lp_fact;
290299};
291300
292301template <int m_N, int _storage_N>
r30979r30980
296305
297306   netlist_matrix_solver_gauss_seidel_t(int size)
298307      : netlist_matrix_solver_direct_t<m_N, _storage_N>(size)
308      , m_lp_fact(0)
299309      , m_gs_fail(0)
300310      , m_gs_total(0)
301311      {}
r30979r30980
304314
305315    ATTR_COLD virtual void log_stats();
306316
317    ATTR_HOT inline int vsolve_non_dynamic();
307318protected:
308   ATTR_HOT int vsolve_non_dynamic();
319    ATTR_HOT virtual double vsolve();
309320
310321private:
322    double m_lp_fact;
311323    int m_gs_fail;
312324    int m_gs_total;
313325
r30979r30980
320332    netlist_matrix_solver_direct1_t()
321333      : netlist_matrix_solver_direct_t<1, 1>(1)
322334      {}
335    ATTR_HOT inline int vsolve_non_dynamic();
323336protected:
324    ATTR_HOT int vsolve_non_dynamic();
337    ATTR_HOT virtual double vsolve();
325338private:
326339};
327340
r30979r30980
332345    netlist_matrix_solver_direct2_t()
333346      : netlist_matrix_solver_direct_t<2, 2>(2)
334347      {}
348    ATTR_HOT inline int vsolve_non_dynamic();
335349protected:
336    ATTR_HOT int vsolve_non_dynamic();
350    ATTR_HOT virtual double vsolve();
337351private:
338352};
339353
trunk/src/emu/netlist/nl_base.c
r30979r30980
460460   , m_time(netlist_time::zero)
461461   , m_active(0)
462462   , m_in_queue(2)
463    , m_new_Analog(0.0)
464463    , m_last_Analog(0.0)
465464    , m_cur_Analog(0.0)
466465{
r30979r30980
500499         m_last_Analog = m_cur_Analog; // FIXME: Needed here ?
501500         railterminal().netdev().inc_active();
502501         m_cur_Q = m_new_Q;
503         m_cur_Analog = m_new_Analog;
504502      }
505503   }
506504
r30979r30980
514512      else
515513      {
516514         m_cur_Q = m_last_Q = m_new_Q;
517         m_cur_Analog = m_last_Analog = m_new_Analog;  // FIXME: Needed here?
515         m_last_Analog = m_cur_Analog;
518516         m_in_queue = 2;
519517      }
520518   }
r30979r30980
553551    m_cur_Q = 0;
554552    m_last_Analog = 0.0;
555553    m_cur_Analog = 0.0;
556    m_new_Analog = 0.0;
557554
558555   /* rebuild m_list */
559556
r30979r30980
592589   save(NAME(m_in_queue));
593590    save(NAME(m_last_Analog));
594591    save(NAME(m_cur_Analog));
595    save(NAME(m_new_Analog));
596592    save(NAME(m_last_Q));
597593    save(NAME(m_cur_Q));
598594    save(NAME(m_new_Q));
r30979r30980
723719   m_in_queue = 2; /* mark as taken ... */
724720   m_cur_Q = m_new_Q;
725721
726   m_cur_Analog = m_new_Analog;
727
728722    switch (m_active)
729723    {
730724    case 2:
r30979r30980
859853
860854   net().as_analog().m_last_Analog = 0.97;
861855   net().as_analog().m_cur_Analog = 0.98;
862   net().as_analog().m_new_Analog = 0.99;
863856}
864857
865858ATTR_COLD void netlist_analog_output_t::initial(const double val)
866859{
867860   net().as_analog().m_cur_Analog = val * 0.98;
868861   net().as_analog().m_cur_Analog = val * 0.99;
869   net().as_analog().m_new_Analog = val * 1.0;
870862}
871863
872864// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/nl_base.h
r30979r30980
619619    // We have to have those on one object. Dividing those does lead
620620    // to a significant performance hit
621621    // FIXME: Have to fix the public at some time
622    double m_new_Analog;
623622    double m_last_Analog;
624623    double m_cur_Analog;
625624
r30979r30980
13441343
13451344ATTR_HOT inline void netlist_analog_output_t::set_Q(const double newQ)
13461345{
1347    if (newQ != net().as_analog().m_new_Analog)
1346    if (newQ != net().as_analog().m_cur_Analog)
13481347    {
1349        net().as_analog().m_new_Analog = newQ;
1348        net().as_analog().m_cur_Analog = newQ;
13501349        net().push_to_queue(NLTIME_FROM_NS(1));
13511350    }
13521351}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team