Skip to content

Commit

Permalink
FlightIntegrator and friends micro-optimization (#230)
Browse files Browse the repository at this point in the history
* Library methods reorganization

* A bunch of FlightIntegrator and VesselPrecalculate optimizations, mainly relevant in large part count situations. More can be done : I didn't touch yet stuff specific to aero situations (drag, conduction occlusion...) and there is probably something to be done about Integrate()

* Many experimental perf improvements, basically a big collection of micro-optimizations for various pieces of code running every frame on every part. Won't do much in low part count situations, and some patches are highly situational (atmospheric flight, docking ports, struts, particles repositionning on floating origin shifts...)
Patches affecting the FlightIntegrator and VesselPrecalculate are broably incompatible with mods trying to override/extend stuff through MFI. There are a bunch of perf issues with "end of the call stack" methods being inefficient because they do extra work that is already done at the call site or can be made faster by using state from the call site, so patching those methods doesn't cut it, but this mean many stock methods aren't called anymore, so if those methods are replaced/prefixed/postfixed with MFI, things will break. Notable examples are FI.UpdateAerodynamics() and FI.Integrate(Part). This could probably be avoided at the cost of some of the perf gains, but I wanted to see how far things could be pushed perf wise.
On a side note, there is a bug lurking in the VesselPrecalculate.CalculatePhysicsStats reimplementation, not sure what it is exactely but a side effect is camera target being wrongly offset. Likely something with the CoM calcs.

* Fix incorrect vessel localCom when root part is not the control point
-most notably this caused the camera to be anchored to the wrong place

---------

Co-authored-by: JonnyOThan <jonnyothan@gmail.com>
  • Loading branch information
gotmachine and JonnyOThan authored Oct 7, 2024
1 parent 441f2d7 commit 7346056
Show file tree
Hide file tree
Showing 8 changed files with 2,711 additions and 29 deletions.
4 changes: 4 additions & 0 deletions GameData/KSPCommunityFixes/Settings.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,10 @@ KSP_COMMUNITY_FIXES
// state synchronization and caching solar panels scaled space raycasts results.
OptimizedModuleRaycasts = true
// General micro-optimization of FlightIntegrator and VesselPrecalculate, significantely increase
// framerate in large part count situations.
FlightPerf = true
// ##########################
// Modding
// ##########################
Expand Down
4 changes: 4 additions & 0 deletions KSPCommunityFixes/KSPCommunityFixes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
<DoNotPublicize Include="Assembly-CSharp:SaveUpgradePipeline.SaveUpgradePipeline.OnSetCfgNodeVersion" />
<Publicize Include="UnityEngine.CoreModule:UnityEngine.Object.m_CachedPtr" />
<Publicize Include="UnityEngine.IMGUIModule" />
<Publicize Include="UnityEngine.CoreModule:Unity.Collections.NativeArray`1.m_Buffer" />
<Publicize Include="mscorlib:System.IO.MonoIO" />
<Publicize Include="mscorlib:System.IO.MonoIOError" />
<Publicize Include="mscorlib:System.IO.MonoIOStat" />
Expand Down Expand Up @@ -124,8 +125,10 @@
<Compile Include="BugFixes\StrategyDuration.cs" />
<Compile Include="BugFixes\ZeroCostTechNodes.cs" />
<Compile Include="Library\Collections\Deque.cs" />
<Compile Include="Library\Collections\FastStack.cs" />
<Compile Include="Library\Extensions.cs" />
<Compile Include="Library\LocalizationUtils.cs" />
<Compile Include="Library\Numerics.cs" />
<Compile Include="Library\ObjectPool.cs" />
<Compile Include="Modding\ModUpgradePipeline.cs" />
<Compile Include="Performance\AsteroidAndCometDrillCache.cs" />
Expand All @@ -138,6 +141,7 @@
<Compile Include="Performance\DisableMapUpdateInFlight.cs" />
<Compile Include="Performance\DragCubeGeneration.cs" />
<Compile Include="Performance\FastLoader.cs" />
<Compile Include="Performance\FlightPerf.cs" />
<Compile Include="Performance\IMGUIOptimization.cs" />
<Compile Include="Performance\LocalizerPerf.cs" />
<Compile Include="Performance\LowerMinPhysicsDTPerFrame.cs" />
Expand Down
43 changes: 43 additions & 0 deletions KSPCommunityFixes/Library/Collections/FastStack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Runtime.CompilerServices;

namespace KSPCommunityFixes.Library.Collections
{
internal class FastStack<T> where T : class
{
private T[] _array = Array.Empty<T>();
private int _size;

public void EnsureCapacity(int capacity)
{
if (_array.Length < capacity)
_array = new T[capacity];
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Push(T item)
{
_array[_size++] = item;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryPop(out T result)
{
if (_size == 0)
{
result = null;
return false;
}

result = _array[--_size];
_array[_size] = null;
return true;
}

public void Clear()
{
Array.Clear(_array, 0, _size);
_size = 0;
}
}
}
60 changes: 45 additions & 15 deletions KSPCommunityFixes/Library/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;

namespace KSPCommunityFixes
{
static class Extensions
{
/// <summary>
/// Transforms a direction by this matrix.
/// </summary>
public static Vector3 MultiplyVector(this Matrix4x4 m, float x, float y, float z)
{
return new Vector3(
m.m00 * x + m.m01 * y + m.m02 * z,
m.m10 * x + m.m11 * y + m.m12 * z,
m.m20 * x + m.m21 * y + m.m22 * z);
}

/// <summary>
/// Get an assembly qualified type name in the "assemblyName:typeName" format
/// </summary>
Expand All @@ -34,4 +22,46 @@ public static bool IsPAWOpen(this Part part)
return part.PartActionWindow.IsNotNullOrDestroyed() && part.PartActionWindow.isActiveAndEnabled;
}
}

static class ParticleBuffer
{
private static NativeArray<ParticleSystem.Particle> particleBuffer = new NativeArray<ParticleSystem.Particle>(1000, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
private static long particleSize = UnsafeUtility.SizeOf<ParticleSystem.Particle>();

/// <summary>
/// Get a native array of active Particle in this ParticleSystem
/// </summary>
/// <param name="particleCount">The amount of particles in the system, usually ParticleSystem.particleCount. After returning, this will be the amount of active particles, which might be lower.</param>
/// <returns></returns>
public static NativeArray<ParticleSystem.Particle> GetParticlesNativeArray(this ParticleSystem particleSystem, ref int particleCount)
{
if (particleBuffer.Length < particleCount)
{
particleBuffer.Dispose();
particleBuffer = new NativeArray<ParticleSystem.Particle>(particleCount * 2, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
}
particleCount = particleSystem.GetParticles(particleBuffer);
return particleBuffer;
}

/// <summary>
/// Get the position of the particle at the specified index, avoiding to have to make copies of the (huge) particle struct
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Vector3 GetParticlePosition(this NativeArray<ParticleSystem.Particle> buffer, int particleIndex)
{
// note : the position Vector3 is the first field of the struct
return *(Vector3*)((byte*)buffer.m_Buffer + particleIndex * particleSize);
}

/// <summary>
/// Set the position of the particle at the specified index, avoiding to have to make copies of the (huge) particle struct
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void SetParticlePosition(this NativeArray<ParticleSystem.Particle> buffer, int particleIndex, Vector3 position)
{
// note : the position Vector3 is the first field of the struct
*(Vector3*)((byte*)buffer.m_Buffer + particleIndex * particleSize) = position;
}
}
}
Loading

0 comments on commit 7346056

Please sign in to comment.