neuoy / KSPTrajectories

A Kerbal Space Program mod to display trajectory predictions, accounting for atmospheric drag, lift, etc.
GNU General Public License v3.0
144 stars 47 forks source link

Multi-Threaded prediction calculations #123

Open PiezPiedPy opened 6 years ago

PiezPiedPy commented 6 years ago

I'm wondering if creating separate threads for the Trajectory calculations would be possible, since at present the calculations are done on the Unity Main-Thread and thus they are computed only on one core along with everything else Unity does.

As an example when I'm running KSP on my system, I'm at 15% CPU usage but one core is at 95-100% due to Unity's lack of Multi-threading. (2 x Opteron 6238 @ 3.2GHz / 24 cores total, it's not a gaming rig but for CAD/FEA in the work I do with Automotive Engineering).

If possible I will move the calculations into their own threads, I've got a lot of experience writing multi-threaded automotive networking software, so if the Trajectory calculations can be parallelized I should be able to assign them to multiple threads.

Even if the calculations are serial then just one separate thread to push the calculations onto a separate core should yield better performance, especially on slower clocked CPU's.

fat-lobyte commented 6 years ago

I have thought about this before, but as far as I can see, that would not be possible.

What takes most of the calculation time (when cache-less) is the StockAeroUtil.SimAeroForce() function. This function references several Game objects, including the current Vessel and the target Body.

I think accessing these game objects from any thread other than the Unity main thread is forbidden and results in race conditions. If we synchronized these calls somehow, we would probably lose all of our performance benefit from multi-threaded calculations.

At least that's the conclusion to which I came after thinking about that last time. You're obviously welcome to try and figure out a way yourself!

PiezPiedPy commented 6 years ago

I think accessing these game objects from any thread other than the Unity main thread is forbidden and results in race conditions. If we synchronized these calls somehow, we would probably lose all of our performance benefit from multi-threaded calculations.

Very true, my idea was to take a snapshot of any Game object data and pass it on so the separate thread would not need to access the Game objects, as such I have only had a quick look at the calculation code and I am also not sure if there is any benefit.

At least that's the conclusion to which I came after thinking about that last time. You're obviously welcome to try and figure out a way yourself!

I'll have a good look at the calculation code and cross my fingers.

fat-lobyte commented 5 years ago

@PiezPiedPy is this something you deem realistic? If not, I'd like to close this issue.

PiezPiedPy commented 4 years ago

Just a heads up that his is coming along nicely, no time on when it will be complete but so far I have cached the needed GameData and incorporated it into the Trajectory calculations. No problems yet, fingers crossed.

Next is using code from one of my multithreading classes I use in vehicle networking (OBDII stuff). Now the fun begins 😎

PiezPiedPy commented 4 years ago

Decided to start a new branch rather than keeping my work local, currently working through my changes and converting it to commits on the branch.

branch is here https://github.com/neuoy/KSPTrajectories/tree/Multithreaded

PiezPiedPy commented 4 years ago

So I now have the trajectory calculation now running in it's own thread 😁 but I've hit a few snags in the StockAeroUtil.SimAeroForce method 😞

Hopefully not a big problem, looks like I will have to also copy the part Transforms into the GameDataCache, copying the parts themselves is not enough.

If I get the stock model working next will be testing using the FAR model 😬

PiezPiedPy commented 4 years ago

StockAeroUtil.SimAeroForce is mostly working now, I need to work on transform.InverseTransformDirection and the transform.TransformDirection methods.

Also getting weird sporadic things happening every few seconds with the GetGroundAltitude method in Trajectory.cs, the PQS class is giving index out of range exceptions and strange graphical artefacts on planets, cant fathom it out 😠, hope I can get to the bottom of it.

Apart from the above problems the Stock model is working fine, can bump the settings to max 10 patches and 0.1 integrator step with no game lag 😃

PiezPiedPy commented 3 years ago

I've found a workaround for the PQS problems by making copies of the planets height data, this height data is stored on file so it only needs to be calculated once.

The height data can be updated via the GUI if KSP changes its planet data or a mod is used that modifies the planets. I also plan on adding a resolution parameter to the GUI so that the user can balance data size vs precision.

fat-lobyte commented 3 years ago

Hi @PiezPiedPy , how are you progressing with your multithreaded calculation and what are your plans?

I ask because I want to slowly get back into modding, and i want to start with a few small changes.

However, i absolutely don't want to interfere with your efforts and cause unnecessary merge conflicts. What can I touch and what should I not?

PiezPiedPy commented 3 years ago

@fat-lobyte 👋

Plans are to cache PQS planet data, copy the math from some methods that are used by KSP and Unity and place the code into thread safe variations.

The multithreaded branch works fine apart from a few accesses to classes/methods that have been moved, changed, removed etc by the game thread, which is to be expected, using dnSpy and reversing the dll's has been the trick in working out the math needed to create the thread safe variants.

There are only a small amount of methods left to make thread safe 😉 but real-life commitments have left me with little time lately, so work on this has been sporadic.

tbh feel free to change what you need, I'll work around you and cherry-pick commits into the multithreaded branch.

PiezPiedPy commented 3 years ago

PQS data is now sampled and used by the trajectory thread and so far all has been good with testing.

End of the tunnel is getting nearer 😃