Skip to content

foonix

5 posts by foonix

Chipping Away at Map View Performance Issues

Chipping away at map view performance issues

Most of the speedups in Redux focus on the simulation and main UI. We haven’t really done much to try to improve the map situation. After all, the simulation has to run at time as the map being open, so any improvement in the simulation should imply a performance improvement in the map. However, with the sim performance getting better, the FPS drop when opening the map is getting increasingly noticeable. One piece of code in particular, called RelativeOrbitSolver jumped out at me as actually getting worse due to some changes in the way transforms are handled. The current version in redux takes up a whopping 4ms on my test setup.

RelativeOrbitSolver is used for predicting future locations in a hypothetical future orbit, and calculate where those points would be with respect to some given viewer. It’s used by the map to do things like draw projected intercept lines.

For example, let’s say a vessel in orbit of Kerbol is not currently intercepting Moho. The player adds a maneuver plan that would cause it to intercept Moho’s SOI but transit through it. So, the map has to draw a bunch of different lines.

  • The current orbit line.
  • The line starting at where the maneuver node is showing the change in Kerbol orbit as a result of the planned impulse. Ends at the predicted Moho SOI intercept.
  • A line near wherever Moho currently is that shows the vessel’s predicted transit through Moho’s SOI (relative to Moho). This is technically a hyperbolic trajectory (“orbit”) of Moho.
  • Another line relative to Kerbol that shows what the previous line actually like from Kerbol’s perspective. This is the one that uses RelativeOrbitSolver.
  • A line after the projected SOI ejection that shows yet another orbit of Kerbol, but this one having been modified by Moho’s gravitational pull.

The code uses several strategies depending on what kind of line it’s drawing, but the 2nd to last one here is the one that uses RelativeOrbitSolver. It’s also used for some other tasks, such as trying to find SOI transition points.

The code for RelativeOrbitSolver is one of the few things got somewhat slower after switching to ECS frames. It created a bunch of temporary TransformModels, would move them around, and then use them for doing relative position calculations. The individual point calculations were probably faster, however the setup/teardown of the temporary frames were quite expensive. Unfortunately, a few spots in the code (such as maneuver nodes) would create a RelativeOrbitSolver to solve for exactly one point and throw it away.

So, I rewrote the code to avoid using TransformModel. While I was in there, I noticed a bug where it would ignore a celestial body’s axialTilt, which caused some issues with the line related to Moho. Now the code just scrapes the spatial relationships into a simple temporary list, and runs a simple loop to do the same calculations the more complicated transform system would do.

Map view performance 1

Map view performance 2

Map view performance 3

Improving Performance of Background Part Modules

Improving performance of background part modules.

Some of you may remember the infamous “2500 background parts” test thread from the forum.

If you’re not familiar, it was a test using 10x250 part vessels in the background, and a single capsule in the foreground.

https://forum.kerbalspaceprogram.com/topic/219210-ksp2-is-calculating-the-physics-of-all-parts-of-all-crafts-whether-they-are-rendered-or-not-reducing-performance-of-all-scenes-at-all-times/

So far, Redux has incidentally made some small improvements on that test. The development branch is about %15-20 faster than stock, mostly due to general improvements in spatial calculations and flow request processing.

However, I hadn’t really tried to tackle the elephant in the room, which is just the shear amount of parts. Even tiny amounts of overhead for each part really adds up when we’re talking about multiple thousands of them. One save a player shared with me had organically hit 560 parts even while keeping per-vessel part count low, so it’s not really far fetched that real players could hit 1000+ parts.

So I took a look back at the 2500 parts test, and was able get another ~%10 more fps with a couple of relatively simple changes. (51.4ms -> 46.2ms)

  • Reworked the part module update code to make modules have to subscribe to get updates. Skip ones that don’t subscribe, and implement subscription for ones that do.
  • Moved some engine status display updates from background to foreground only.
  • Moved Module_LitPart checking if the lights should be on/off to foreground only. (Note, this is different from Module_Light. It just checks if the vessel should look like it’s had a power failure or not.)
  • Simplified some getter logic commonly used by modules.

All in, Redux runs the test about %30 faster on my machine. Stock KSP2 vs this branch: 16fps -> 21fps

Left/Blue is Redux development branch. Right/orange is this change set. Comparison over 384 frames.

Background part modules 1

Background part modules 2

Performance Improvements Overview

Basic rundown of Redux FPS improvements:

Leverage newer unity features

  • Enable unity “Graphics Jobs” setting. Cuts 3-5ms off the frame on my computer.
  • Disable Unity Physics.autoSyncTransforms option. This required rewriting a lot of code to avoid depending on the autosync behavior.

Overhaul widely used systems for better performance

TransformFrame is how the game deals with multiple moving reference frames, and is used extensively through the code base. Redux replaces this with an ECS/Burst based system that is significantly faster.

Lots of individually minor “depessimizations” that add up to significant improvements.

Too many to list in a discord comment. Many, many code systems have been tweaked to remove unnecessary steps, fix unnecessary garbage allocations, and accomplish the same task with fewer resources.

Performance test results compilation

All tests are on my system: i7-4790K @ 4GHz, 32GB DDR3 @1333MHz, RTX2080

Small vessel test:

50 fps -> 78 fps

200 part test:

18 fps, 55.95ms/frame -> 24fps, 41.49ms/frame

1500 part test

638 ms/frame -> 347 ms/frame

Unable to recover small-vessel-redux.png from Discord: HTTP Error 404: Not Found

Unable to recover small-vessel-stock.png from Discord: HTTP Error 404: Not Found

200 part test 1

200 part test 2

Unable to recover 1500-part-test-1.png from Discord: HTTP Error 404: Not Found

Unable to recover 1500-part-test-2.png from Discord: HTTP Error 404: Not Found