From db1e85e69ddf84aa24e9f99782eb7765a3ba0048 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 5 Dec 2022 00:44:50 +0100 Subject: [PATCH] Warmup system to speed up startup. --- Robust.Client/ClientWarmup.cs | 28 +++++++++++++++++++ .../GameController.Standalone.cs | 2 ++ Robust.Server/Program.cs | 2 ++ Robust.Server/ServerWarmup.cs | 20 +++++++++++++ Robust.Shared/Resources/RsiLoading.cs | 6 ++++ Robust.Shared/SharedWarmup.cs | 21 ++++++++++++++ 6 files changed, 79 insertions(+) create mode 100644 Robust.Client/ClientWarmup.cs create mode 100644 Robust.Server/ServerWarmup.cs create mode 100644 Robust.Shared/SharedWarmup.cs diff --git a/Robust.Client/ClientWarmup.cs b/Robust.Client/ClientWarmup.cs new file mode 100644 index 0000000000..57ce11d91e --- /dev/null +++ b/Robust.Client/ClientWarmup.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Robust.Shared; +using Robust.Shared.Resources; +using SixLabors.ImageSharp; + +namespace Robust.Client; + +/// +/// Logic for "warming up" things like slow static constructors concurrently. +/// +internal static class ClientWarmup +{ + public static void RunWarmup() + { + Task.Run(WarmupCore); + } + + private static void WarmupCore() + { + // Get ImageSharp loaded. + _ = Configuration.Default; + + SharedWarmup.WarmupCore(); + + // Preload the JSON loading code. + RsiLoading.Warmup(); + } +} diff --git a/Robust.Client/GameController/GameController.Standalone.cs b/Robust.Client/GameController/GameController.Standalone.cs index c89099a2a4..550e2ff49b 100644 --- a/Robust.Client/GameController/GameController.Standalone.cs +++ b/Robust.Client/GameController/GameController.Standalone.cs @@ -45,6 +45,8 @@ namespace Robust.Client private static void ParsedMain(CommandLineArgs args, bool contentStart, IMainArgs? loaderArgs, GameControllerOptions options) { + ClientWarmup.RunWarmup(); + var deps = IoCManager.InitThread(); var mode = args.Headless ? DisplayMode.Headless : DisplayMode.Clyde; diff --git a/Robust.Server/Program.cs b/Robust.Server/Program.cs index 811d8c6cac..d711768f5a 100644 --- a/Robust.Server/Program.cs +++ b/Robust.Server/Program.cs @@ -48,6 +48,8 @@ namespace Robust.Server private static void ParsedMain(CommandLineArgs args, bool contentStart, ServerOptions options) { + ServerWarmup.RunWarmup(); + Thread.CurrentThread.Name = "Main Thread"; var deps = IoCManager.InitThread(); ServerIoC.RegisterIoC(deps); diff --git a/Robust.Server/ServerWarmup.cs b/Robust.Server/ServerWarmup.cs new file mode 100644 index 0000000000..537ee33a74 --- /dev/null +++ b/Robust.Server/ServerWarmup.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Robust.Shared; + +namespace Robust.Server; + +/// +/// Logic for "warming up" things like slow static constructors concurrently. +/// +internal static class ServerWarmup +{ + public static void RunWarmup() + { + Task.Run(WarmupCore); + } + + private static void WarmupCore() + { + SharedWarmup.WarmupCore(); + } +} diff --git a/Robust.Shared/Resources/RsiLoading.cs b/Robust.Shared/Resources/RsiLoading.cs index 86eca2942a..8a9853c7be 100644 --- a/Robust.Shared/Resources/RsiLoading.cs +++ b/Robust.Shared/Resources/RsiLoading.cs @@ -96,6 +96,12 @@ internal static class RsiLoading return new RsiMetadata(size, states); } + public static void Warmup() + { + // Just a random RSI I pulled from SS14. + const string warmupJson = @"{""version"":1,""license"":""CC-BY-SA-3.0"",""copyright"":""Space Wizards Federation"",""size"":{""x"":32,""y"":32},""states"":[{""name"":""mono""}]}"; + JsonSerializer.Deserialize(warmupJson, SerializerOptions); + } internal sealed class RsiMetadata { diff --git a/Robust.Shared/SharedWarmup.cs b/Robust.Shared/SharedWarmup.cs new file mode 100644 index 0000000000..0b6e6ada58 --- /dev/null +++ b/Robust.Shared/SharedWarmup.cs @@ -0,0 +1,21 @@ +using System.Runtime.CompilerServices; +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; + +namespace Robust.Shared; + +/// +/// Logic for "warming up" things like slow static constructors concurrently. +/// +internal static class SharedWarmup +{ + [MethodImpl(MethodImplOptions.NoOptimization)] + public static void WarmupCore() + { + // Color's cctor unironically takes ~12ms. + RuntimeHelpers.RunClassConstructor(typeof(Color).TypeHandle); + + // This ends up initializing prometheus-net which takes quite a while. + RuntimeHelpers.RunClassConstructor(typeof(EntitySystemManager).TypeHandle); + } +}