Board index FlightGear Development Canvas

Canvas performance (property overhead) (pm/space shuttle)

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Canvas performance (property overhead) (pm/space shuttle)

Postby Hooray » Mon Nov 30, 2015 7:38 pm

Space Shuttle
Thorsten wrote:I suppose in terms of raw information content (with sometimes close to 100 properties displayed) the DPS screens are sort of record-breaking (but then again, no one today would design interfaces that way any more).
[...]
I start being concerned about the performance impact of 100+ getprop() statements per display update...

(I suppose once we support more displays, we have to run them asynchonously to avoid peak loads during the update frames.)



We were recently talking about that, too - i.e. re-publishing some behind-the scenes exchanges:

Hooray wrote:I was going to take another look at the pui2canvas parser, as well as supporting the "peformance monitor" (dynamic vis Nasal/dialog-show/update) and port/integrate that with the reset/re-init Canvas dialog below:

Image

I don't know if you have ever tried using the built-in google perftools profiler in conjunction with the recent GUI work, but the performance monitor using PUI and Nasal is already a very real bottleneck, and it remains a bottleneck even when using Canvas, because certain things are not possible/efficient, when using Nasal.

Under the hood, it is all about updating properties and updating a label/text element accordingly, we could dramaticaly reduce the degree of Nasal overhead by allowing text to be specified using printf-style format strings that get their values from a sub-branch in the element's tree (one node for each %s, %d) - that way, the whole thing could be processed in C++ space, and we would not need to use any Nasal for updating/building strings.

If this could be supported, we could also provide two modes: polling and on-update, to ensure that there is no unnecessary C++ overhead.

Complex dialogs with lots of dynamic labels could then be re-implemented much more easily, without having to register 5-10 callbacks per metrics (or timers/listeners), even though a timer-based update mode may also be useful for the C++ change.

Note that this would also be useful for the PUI parser itself, because that already supports values that may be provided by a property using printf-style formatting, there, it is limited to a single fomat string - with Canvas, we could support an arbitrary number of sub-nodes that are updated as needed.

Ultimately, that would also help with HUD/2D panels stuff, because taking values from properties and updating them using sprintf-style code is extremely common there, too - and we could avoid tons of Nasal overhead like that.

(no response needed/expected - consider this just feedback for now, based on profiling/coding experiments)
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11329
Joined: Tue Mar 25, 2008 8:40 am

Re: Canvas performance (property overhead) (pm/space shuttle

Postby Hooray » Tue Dec 01, 2015 2:43 pm

Note that when/if we should explore supporting this, we should probably avoid using Boost.Format here, which is known for being much slower in comparison to its alternatives:

http://www.boost.org/doc/libs/1_52_0/li ... mance.html
Image

The generally recommended alternative being "cppformat" (BSD) instead: https://github.com/cppformat/cppformat#speed-tests

API: http://cppformat.github.io/latest/refer ... -functions
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11329
Joined: Tue Mar 25, 2008 8:40 am

Re: Canvas performance (property overhead) (pm/space shuttle

Postby Hooray » Thu Dec 17, 2015 10:28 pm

Just for future reference, here's an excerpt from the space shuttle avionics showing the degree of dynamically-updated sprintf-based property/labels:

(in other words, we have a real use-case here !)

http://sourceforge.net/p/fgspaceshuttle ... pu_hyd.nas
Code: Select all
p_dps_apu_hyd.update = func
    {
   
        p_dps_apu_hyd.speed_pct_1.setText(sprintf("%4.0f", 100.0 * getprop("/fdm/jsbsim/systems/apu/apu/apu-rpm-fraction")));
        p_dps_apu_hyd.speed_pct_2.setText(sprintf("%4.0f", 100.0 * getprop("/fdm/jsbsim/systems/apu/apu[1]/apu-rpm-fraction")));
        p_dps_apu_hyd.speed_pct_3.setText(sprintf("%4.0f", 100.0 * getprop("/fdm/jsbsim/systems/apu/apu[2]/apu-rpm-fraction")));
   
   
        p_dps_apu_hyd.fuel_qty_1.setText(sprintf("%4.0f", getprop("/consumables/fuel/tank[14]/level-lbs")/3.5));
        p_dps_apu_hyd.fuel_qty_2.setText(sprintf("%4.0f", getprop("/consumables/fuel/tank[15]/level-lbs")/3.5));
        p_dps_apu_hyd.fuel_qty_3.setText(sprintf("%4.0f", getprop("/consumables/fuel/tank[16]/level-lbs")/3.5));
   
        p_dps_apu_hyd.vlv_a_1.setText(sprintf("  %s", valve_status_to_string(getprop("/fdm/jsbsim/systems/apu/apu/fuel-valve-status"))));
        p_dps_apu_hyd.vlv_a_2.setText(sprintf("  %s", valve_status_to_string(getprop("/fdm/jsbsim/systems/apu/apu[1]/fuel-valve-status"))));
        p_dps_apu_hyd.vlv_a_3.setText(sprintf("  %s", valve_status_to_string(getprop("/fdm/jsbsim/systems/apu/apu[2]/fuel-valve-status"))));
   
        p_dps_apu_hyd.vlv_b_1.setText(sprintf("  %s", valve_status_to_string(getprop("/fdm/jsbsim/systems/apu/apu/fuel-valve-status"))));
        p_dps_apu_hyd.vlv_b_2.setText(sprintf("  %s", valve_status_to_string(getprop("/fdm/jsbsim/systems/apu/apu[1]/fuel-valve-status"))));
        p_dps_apu_hyd.vlv_b_3.setText(sprintf("  %s", valve_status_to_string(getprop("/fdm/jsbsim/systems/apu/apu[2]/fuel-valve-status"))));
   
        p_dps_apu_hyd.oil_t_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/oil-in-T-K"))));
        p_dps_apu_hyd.oil_t_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/oil-in-T-K"))));
        p_dps_apu_hyd.oil_t_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/oil-in-T-K"))));
   
        p_dps_apu_hyd.oil_outt_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/thermal-distribution/apu1-temperature-K"))));
        p_dps_apu_hyd.oil_outt_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/thermal-distribution/apu2-temperature-K"))));
        p_dps_apu_hyd.oil_outt_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/thermal-distribution/apu3-temperature-K"))));
   
        p_dps_apu_hyd.bu_p_1.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu/hyd-pressure-psia")));
        p_dps_apu_hyd.bu_p_2.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[1]/hyd-pressure-psia")));
        p_dps_apu_hyd.bu_p_3.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[2]/hyd-pressure-psia")));
   
        p_dps_apu_hyd.h2o_1.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/propulsion/tank[20]/contents-lbs")/1.42));
        p_dps_apu_hyd.h2o_2.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/propulsion/tank[21]/contents-lbs")/1.42));
        p_dps_apu_hyd.h2o_3.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/propulsion/tank[22]/contents-lbs")/1.42)); 
   
        p_dps_apu_hyd.cntlr_1.setText(sprintf(" %s", wsb_ctrl_to_string(getprop("/fdm/jsbsim/systems/apu/apu/boiler-power-status"))));
        p_dps_apu_hyd.cntlr_2.setText(sprintf(" %s", wsb_ctrl_to_string(getprop("/fdm/jsbsim/systems/apu/apu[1]/boiler-power-status"))));
        p_dps_apu_hyd.cntlr_3.setText(sprintf(" %s", wsb_ctrl_to_string(getprop("/fdm/jsbsim/systems/apu/apu[2]/boiler-power-status"))));
   
        p_dps_apu_hyd.bu_egt_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/egt-K")-3.0)));
        p_dps_apu_hyd.bu_egt_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/egt-K")+1.0)));
        p_dps_apu_hyd.bu_egt_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/egt-K")-4.0)));
   
        p_dps_apu_hyd.egt_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/egt-K")+1.0)));
        p_dps_apu_hyd.egt_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/egt-K")-1.0)));
        p_dps_apu_hyd.egt_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/egt-K"))));
   
        p_dps_apu_hyd.accum_p_1.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu/hyd-acc-pressure-psia")));
        p_dps_apu_hyd.accum_p_2.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[1]/hyd-acc-pressure-psia")));
        p_dps_apu_hyd.accum_p_3.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[2]/hyd-acc-pressure-psia")));
   
        p_dps_apu_hyd.rsvr_t_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/hyd-rsvr-T-K")-3.0)));
        p_dps_apu_hyd.rsvr_t_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/hyd-rsvr-T-K")+1.0)));
        p_dps_apu_hyd.rsvr_t_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/hyd-rsvr-T-K"))));
   
        var ggbed_T1 = getprop("/fdm/jsbsim/systems/apu/apu/gg-bed-T-K");
        var ggbed_T1_sym = "";
        if (ggbed_T1 > 540) {ggbed_T1_sym = "H"; ggbed_T1 = 540.0;}
   
        var ggbed_T2 = getprop("/fdm/jsbsim/systems/apu/apu[1]/gg-bed-T-K");
        var ggbed_T2_sym = "";
        if (ggbed_T2 > 540) {ggbed_T2_sym = "H"; ggbed_T2 = 540.0;}
   
        var ggbed_T3 = getprop("/fdm/jsbsim/systems/apu/apu[2]/gg-bed-T-K");
        var ggbed_T3_sym = "";
        if (ggbed_T3 > 540) {ggbed_T3_sym = "H"; ggbed_T3 = 540.0;}
   
        p_dps_apu_hyd.ggbed_t_1.setText(sprintf("%4.0f%s", K_to_F(ggbed_T1), ggbed_T1_sym));
        p_dps_apu_hyd.ggbed_t_2.setText(sprintf("%4.0f%s", K_to_F(ggbed_T2-1.0), ggbed_T2_sym));
        p_dps_apu_hyd.ggbed_t_3.setText(sprintf("%4.0f%s", K_to_F(ggbed_T3+3.0), ggbed_T3_sym));
   
   
        p_dps_apu_hyd.vent_t_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/steam-vent-T-K")-3.0)));
        p_dps_apu_hyd.vent_t_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/steam-vent-T-K"))));
        p_dps_apu_hyd.vent_t_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/steam-vent-T-K")+1.0)));
   
        p_dps_apu_hyd.pmp_t_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/fuel-pump-T-K")-1.0)));
        p_dps_apu_hyd.pmp_t_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/fuel-pump-T-K")+3.0)));
        p_dps_apu_hyd.pmp_t_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/fuel-pump-T-K")+2.0)));
   
        p_dps_apu_hyd.vlv_t_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/fuel-pump-T-K")+2.0)));
        p_dps_apu_hyd.vlv_t_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/fuel-pump-T-K")-1.0)));
        p_dps_apu_hyd.vlv_t_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/fuel-pump-T-K")-1.0)));
   
        p_dps_apu_hyd.oil_outp_1.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu/oil-p-psia")));
        p_dps_apu_hyd.oil_outp_2.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[1]/oil-p-psia")));
        p_dps_apu_hyd.oil_outp_3.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[2]/oil-p-psia")));
   
        p_dps_apu_hyd.gbx_p_1.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu/oil-p-psia")-1.0));
        p_dps_apu_hyd.gbx_p_2.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[1]/oil-p-psia")-2.0));
        p_dps_apu_hyd.gbx_p_3.setText(sprintf("%4.0f", getprop("/fdm/jsbsim/systems/apu/apu[2]/oil-p-psia")-1.0));
   
        p_dps_apu_hyd.byp_vlv_1.setText(sprintf(" %s", wsb_vlv_to_string(getprop("/fdm/jsbsim/systems/thermal-distribution/spray-boiler-1-switch"))));
        p_dps_apu_hyd.byp_vlv_2.setText(sprintf(" %s", wsb_vlv_to_string(getprop("/fdm/jsbsim/systems/thermal-distribution/spray-boiler-2-switch"))));
        p_dps_apu_hyd.byp_vlv_3.setText(sprintf(" %s", wsb_vlv_to_string(getprop("/fdm/jsbsim/systems/thermal-distribution/spray-boiler-3-switch"))));
   
        p_dps_apu_hyd.brg_t_1.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu/hyd-rsvr-T-K")+3.0)));
        p_dps_apu_hyd.brg_t_2.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[1]/hyd-rsvr-T-K")+4.0)));
        p_dps_apu_hyd.brg_t_3.setText(sprintf("%4.0f", K_to_F(getprop("/fdm/jsbsim/systems/apu/apu[2]/hyd-rsvr-T-K")+1.0)));
   
        device.update_common_DPS();
   
   
    }
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11329
Joined: Tue Mar 25, 2008 8:40 am


Return to Canvas

Who is online

Users browsing this forum: No registered users and 11 guests