open-simulation-platform / libcosim

OSP C++ co-simulation library
https://open-simulation-platform.github.io/libcosim
Mozilla Public License 2.0
54 stars 10 forks source link

Performance impact when using proxyfmu #722

Open davidhjp01 opened 1 year ago

davidhjp01 commented 1 year ago

Performance difference between simulations with and without proxyfmu is quite significant when tested with the tutorial example (spring-mass-damper) using cosim-cli:

Without proxyfmu (endtime 360, stepsize 0.01): image

With proxyfmu (endtime 360, stepsize 0.01, ran on localhost): image

All ran on Windows, times are measured using PowerShell Measure-Command. The run with proxyfmu includes fmu download time (10 seconds max) but it is still 15 times slower.

Given fmus need to exchange data in every step (including doStep and other house keeping communications), such performance degradation is expected. But need some discussion if there is something that can be optimized (or replace thrift?) to improve the simulation speed.

markaren commented 1 year ago

A low hanging fruit here is to reduce the amount of get/set calls by collecting all the types in a single get/set call rather than one for real/integer/boolean/string. This only effects FMUs that actually transfer more than reals. The current API should allow this now that the async API has been removed.

proxy-fmu was never designed for speed, but focused on ease of use and maintanance. Using raw sockets is defintivly possible, but increases the implementation burden by a huge factor.

Using domain sockets on localhost is another approach, but tests shows that the improvement over TCP/IP is marginal (perhaps 3-5%).

kyllingstad commented 1 year ago

A low hanging fruit here is to reduce the amount of get/set calls by collecting all the types in a single get/set call rather than one for real/integer/boolean/string.

I agree. This is how async_slave was designed. The idea was that async_slave would enable efficient communication with remote slaves, while slave was a lower-level interface for local slaves—basically a layer on top of the FMI C interface.

Now that slave is our only slave API, it may be time to improve it.