Kerbalism / Kerbalism4

Hundreds of Kerbals were killed in the making of this mod.
Other
9 stars 3 forks source link

Jobs/Burst based substepping #25

Open gotmachine opened 3 years ago

gotmachine commented 3 years ago

Replace the managed thread based substepping sim with a Jobs/Burst implementation.

Overview of the substep sim :

In SubStepSim.OnFixedUpdate() (called by Kerbalism.FixedUpdate() before anything else has been done) :

Later in Kerbalism.FixedUpdate(), VesselData.EnvironmentUpdate will be called. The elapsedSeconds parameter is checked against the substep duration "constant" (60s for example).

If elapsedSecond < substepDuration * 2.0 :

else

Data : current implementation performance

Save : 20 vessels.zip

Profiler results (2C/4T@4.5Ghz, Cinebench R20 MT : 1135 / ST : 453) : image

Relevant metrics :

gotmachine commented 3 years ago

Inclusion of radiation evaluation

Like irradiances, radiation evaluation is also subject to huge inaccuracies at high timewarp rates. Ideally, we should move it to the substep simulation. Said plainly, that whole portion of code : https://github.com/Kerbalism/Kerbalism4/blob/1e390eb8ef80632d9a641641f07a571ad1492a49/src/Kerbalism/Database/VesselData/VesselData.cs#L979-L1002 In terms of final output, this translate into getting substepped averages (instead of "current position") for the following VesselData radiation rates (rad/s):

/// <summary> ambiant radiation from the inner belt</summary>
public virtual double EnvRadiationInnerBelt { get; }

/// <summary> ambiant radiation from the outer belt</summary>
public virtual double EnvRadiationOuterBelt { get; }

/// <summary> ambiant radiation from the magnetopause</summary>
public virtual double EnvRadiationMagnetopause { get; }

/// <summary> directional radiation from the surface</summary>
public virtual double EnvRadiationBodies { get; }

/// <summary> directional radiation from the sun(s)</summary>
public virtual double EnvRadiationSolar { get; }

 /// <summary> directional radiation from solar storm</summary>
public virtual double EnvStormRadiation { get; }

/// <summary> proportion of ionizing radiation not blocked by atmosphere</summary>
public virtual double EnvGammaTransparency  { get; }

The current code is a bit messy. The core method to port is the Radiation.Compute() method (which is currently a bit messy and was pending a refactor/cleanup) : https://github.com/Kerbalism/Kerbalism4/blob/1e390eb8ef80632d9a641641f07a571ad1492a49/src/Kerbalism/Radiation/Radiation.cs#L618-L770

You will notice that for each of the above variable, there is a matching boolean. This is because we used to only output the "total" aggregate radiation, and booleans to identify what sources were "active". I quick-and-dirty changed that recently so we have access to the detail rate of each source, but I was also in the process of refactoring the whole thing so EnvRadiationSolar is tracked per sun, and EnvRadiationBodies per body (because they are directional, and I was planning to take that into account, at least for solar radiation). Said otherwise, I intended to move EnvRadiationSolar to the StarFlux structure. But since you already are in the process of extending/refactoring StarFlux to a BodyFlux structure (and processing all bodies internally), we should likely do both from the ground up.

In terms of re-implementation, a quick overview :

You will need to make a "job-safe" copy of the RadiationBody and RadiationModel data structures. All values in those classes are constants, so you only need to make that once. RadiationModel are essentially "templates", so I suggest you aggregate the data in a single "per body" data structure (and in fact, you should use the same data structure for info about stars too, instead of re-getting it every iteration. This is also constant data.)

Belts and magnetopause radiation are computed by evaluating the vessel position against the fields shape, which are represented by math functions. The called methods are a bit all over the place for no reason other than technical debt, but you should be able to rebuild the execution path quite easily by following the execution of Radiation.Compute() (it's entirely self contained, to my knowledge there is nothing modifying the data that this depends on).

Solar/bodies radiation are directional, and affected by other bodies occlusion (and also, they are the same value in RadiationModel). From a physics POV, they are identical to the solar irradiance, so you can likely just merge that into your existing code.

Storm radiation is a bit trickier. As mentioned in #5, I intended to more or less entirely scrap the current per-vessel-random implementation, possibly in favor of generating "cone" storms, where every vessel/body inside the cone is subject to the storm. For now, I would suggest to postpone including storm radiation in the substep sim until this is done.

darco89 commented 11 months ago

beloved modders, i just found out about kerbalism 4. are you still working on it? Cheers!