From b6507657d7ebc285891d691bb0c4ce04a1a2593f Mon Sep 17 00:00:00 2001 From: SadPencil Date: Sun, 4 Jan 2026 21:14:19 +0800 Subject: [PATCH 1/2] Add processor affinity argument for Ares --- ClientGUI/GameProcessLogic.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/ClientGUI/GameProcessLogic.cs b/ClientGUI/GameProcessLogic.cs index 41a51b62b..6e48eaa65 100644 --- a/ClientGUI/GameProcessLogic.cs +++ b/ClientGUI/GameProcessLogic.cs @@ -2,12 +2,15 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; +using System.Threading; + using ClientCore; -using Rampastring.Tools; +using ClientCore.Enums; +using ClientCore.Extensions; using ClientCore.INIProcessing; -using System.Threading; + +using Rampastring.Tools; using Rampastring.XNAUI; -using ClientCore.Extensions; namespace ClientGUI { @@ -83,6 +86,8 @@ public static void StartGameProcess(WindowManager windowManager) GameProcessStarting?.Invoke(); + bool processorAffinityOverride = Environment.ProcessorCount > 1 && SingleCoreAffinity && (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)); + if (UserINISettings.Instance.WindowedMode && UseQres && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Logger.Log("Windowed mode is enabled - using QRes."); @@ -112,7 +117,7 @@ public static void StartGameProcess(WindowManager windowManager) return; } - if (Environment.ProcessorCount > 1 && SingleCoreAffinity) + if (processorAffinityOverride) QResProcess.ProcessorAffinity = (IntPtr)2; } else @@ -124,6 +129,9 @@ public static void StartGameProcess(WindowManager windowManager) else arguments = additionalExecutableName + "-SPAWN"; + if (processorAffinityOverride && ClientConfiguration.Instance.ClientGameType == ClientType.Ares) + arguments += " " + "-AFFINITY:2"; + FileInfo gameFileInfo = SafePath.GetFile(ProgramConstants.GamePath, gameExecutableName); var gameProcess = new Process(); @@ -151,11 +159,8 @@ public static void StartGameProcess(WindowManager windowManager) return; } - if ((RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - && Environment.ProcessorCount > 1 && SingleCoreAffinity) - { + if (processorAffinityOverride) gameProcess.ProcessorAffinity = (IntPtr)2; - } } GameProcessStarted?.Invoke(); From 9bd5263725aaebc412075468e15b99acf812d321 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Sun, 4 Jan 2026 21:30:45 +0800 Subject: [PATCH 2/2] Further refactor the affinity code --- ClientGUI/GameProcessLogic.cs | 47 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/ClientGUI/GameProcessLogic.cs b/ClientGUI/GameProcessLogic.cs index 6e48eaa65..4f28414dd 100644 --- a/ClientGUI/GameProcessLogic.cs +++ b/ClientGUI/GameProcessLogic.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Threading; @@ -28,6 +29,35 @@ public static class GameProcessLogic public static bool UseQres { get; set; } public static bool SingleCoreAffinity { get; set; } + public static bool GetProcessorAffinityValue(out int affinity) + { + if (!(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))) + { + affinity = 0; + return false; + } + + if (Environment.ProcessorCount <= 1) + { + affinity = 1; // Only one CPU core available + return true; + } + + + if (SingleCoreAffinity) + { + affinity = 2; // Use only CPU 1 + return true; + } + else + { + int maximumCpuCountPerProcessorGroup = 64; + int cpuCount = Math.Min(Environment.ProcessorCount, maximumCpuCountPerProcessorGroup); + affinity = (1 << cpuCount) - 2; // All but CPU 0 + return true; + } + } + /// /// Starts the main game process. /// @@ -86,7 +116,7 @@ public static void StartGameProcess(WindowManager windowManager) GameProcessStarting?.Invoke(); - bool processorAffinityOverride = Environment.ProcessorCount > 1 && SingleCoreAffinity && (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)); + bool overrideProcessorAffinity = GetProcessorAffinityValue(out int processorAffinity); if (UserINISettings.Instance.WindowedMode && UseQres && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -117,8 +147,8 @@ public static void StartGameProcess(WindowManager windowManager) return; } - if (processorAffinityOverride) - QResProcess.ProcessorAffinity = (IntPtr)2; + if (overrideProcessorAffinity) + QResProcess.ProcessorAffinity = (IntPtr)processorAffinity; } else { @@ -129,8 +159,11 @@ public static void StartGameProcess(WindowManager windowManager) else arguments = additionalExecutableName + "-SPAWN"; - if (processorAffinityOverride && ClientConfiguration.Instance.ClientGameType == ClientType.Ares) - arguments += " " + "-AFFINITY:2"; + if (overrideProcessorAffinity && ClientConfiguration.Instance.ClientGameType == ClientType.Ares) + { + // Ares defaults to use CPU 0 exclusively, unless explicitly overridden. + arguments += " " + "-AFFINITY:" + processorAffinity.ToString(CultureInfo.InvariantCulture); + } FileInfo gameFileInfo = SafePath.GetFile(ProgramConstants.GamePath, gameExecutableName); @@ -159,8 +192,8 @@ public static void StartGameProcess(WindowManager windowManager) return; } - if (processorAffinityOverride) - gameProcess.ProcessorAffinity = (IntPtr)2; + if (overrideProcessorAffinity) + gameProcess.ProcessorAffinity = (IntPtr)processorAffinity; } GameProcessStarted?.Invoke();