New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better precision and Performance with Runge-Kutta-4 integrator #121
Conversation
We weren't quite done with the local truncation error: Adding the LTE to both the position AND velocity improves precision significantly.
Here is the precision comparison. The columns correspond to the situations that were tested (represented by the .sfs quicksave files in the master branch). The rows correspond to the Integration methods that were tested. Verlet is the old integrator, RK-4 is the new integrator. I tried out 3 different Integration steps: 3.0s, 2.0s and 0.5s. The cells show the deviation in kilometers, where:
As you can see, the RK-4 with an IntegrationStepSize of 2.0 yields about the same or better results as Verlet with a 0.1 stepsize. Decreasing the stepsize did not help much with precision. |
Here is the performance comparison. The columns correspond to the situations that were tested (represented by the .sfs quicksave files in the master branch). The rows correspond to the Integration methods that were tested. Verlet is the old integrator, RK-4 is the new integrator. I tried out 3 different Integration steps: 3.0s, 2.0s and 0.5s. The cells show the performance impact as shown in the Settings-Tab of the Trajectory window, in Milliseconds [ms]. On an Intel Core i5 4690K with a boost clock of 3.9 GHz (4.74 GFLOPS per Core), these are the results:
On an Intel Core i5 3320M with a maximum clock of 3100 MHz, these are the results:
The performance benefit without cache and approximately the same precision is between 4,4 and 5,2 times. Unfortunately, the difference between Verlet with Cache and RK-4 without cache are still a bit too much for comfort, here the cache-less RK-4 can be about 2 times slower than the Verlet with cache on slower systems. Whether or not this is acceptable is a more difficult question, but personally I would always prefer the much higher precision without the cache to a small performance hit. What are your opinions? With this PR merged, I will probably start suggesting to turn off the cache most of the time to users. |
Merged due to lack of negative feedback, a.k.a. "works for me". |
I've had no problems with it and got a performance boost on my system. |
No worries, glad that you could look at it :) |
Got a question regarding the accelerationFunc lambda |
Thanks for bringing this feature to my attention! I checked it out, and it seems the performance is actually a tiny bit worse. This is probably because the main advantage of a local function would be the lack of the creation of a delegate object - but we do need to create a delegate object! The Of course, theoretically it would be possible to manually inline everything into the |
Thanks for checking.
Thanks for letting me know, I didn't look too deeply into how the calculations were performed.
I totally agree with you. |
Up until now, Trajectories used the Verlet integration scheme. This worked kind of alright, however it required a rather small step size, which lead to rather hefty performance penalty.
To alleviate this, the force cache was introduced that sped up the force calculation, but came with its own drawback of decreased precision.
Using a more advanced integration Scheme like the Runga-Kutta 4 Integration allows a much higher integration step (improving performance) while maintaining precision.
There are now 4 invocations of the force function instead of one, but this allowed us to increase the stepsize from 0.1s to 2.0s, resulting in a
2.0 / 0.1 / 4 = 5
-fold performance increase, while maintaining about the same (cache-less) precision.This allows users to disable the cache for no or a small perfomance loss for a high increase in precision.
The step size is now variable and can be changed in the code as
Trajectories.Settings.IntegrationStepSize
or in the settings by adding<float name="IntegrationStepSize">2.0</float>
to/GameData/Trajectories/Plugin/PluginData/Trajectories/config.xml
.What I think should be done before merging this PR:
What I think should be done after merging this PR:
We really need the result at most 0.5 times a second, unless you're doing KOS things.
A compiled version of this branch can be found here:
https://github.com/fat-lobyte/KSPTrajectories/releases/download/v1.7.2-pre_integrator1/Trajectories.dll