diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index dc18038ba..f6911920b 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -10,6 +10,7 @@ using ARMeilleure.State; using ARMeilleure.Translation.Cache; using ARMeilleure.Translation.PTC; using Ryujinx.Common; +using Ryujinx.Common.SystemInfo; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -103,6 +104,7 @@ namespace ARMeilleure.Translation public void Execute(State.ExecutionContext context, ulong address) { + int physicalCoreCount = SystemInfo.GetPhysicalCoreCount(); if (Interlocked.Increment(ref _threadCount) == 1) { IsReadyForTranslation.WaitOne(); @@ -122,10 +124,7 @@ namespace ARMeilleure.Translation // etc). All threads are normal priority except from the last, which just fills as much of the last core // as the os lets it with a low priority. If we only have one rejit thread, it should be normal priority // as highCq code is performance critical. - // - // TODO: Use physical cores rather than logical. This only really makes sense for processors with - // hyperthreading. Requires OS specific code. - int unboundedThreadCount = Math.Max(1, (Environment.ProcessorCount - 6) / 3); + int unboundedThreadCount = Math.Max(1, (physicalCoreCount - 6) / 3); int threadCount = Math.Min(4, unboundedThreadCount); Thread[] backgroundTranslationThreads = new Thread[threadCount]; diff --git a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs index 55ec0127c..c4e941aa4 100644 --- a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs @@ -1,5 +1,8 @@ using Ryujinx.Common.Logging; using System; +using System.Diagnostics; +using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using System.Text; @@ -74,5 +77,51 @@ namespace Ryujinx.Common.SystemInfo return string.IsNullOrEmpty(name) ? null : name; } + + public static int GetPhysicalCoreCount() + { + int coreCount = Environment.ProcessorCount; + + try + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + coreCount = 0; + foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get()) + { + coreCount += int.Parse(item["NumberOfCores"].ToString()); + } + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + coreCount = File.ReadLines("/proc/cpuinfo") + .Count(line => line.Contains("cpu cores")); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "sysctl", + Arguments = "-n hw.physicalcpu", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + } + }; + + process.Start(); + coreCount = int.Parse(process.StandardOutput.ReadToEnd()); + process.WaitForExit(); + } + } + catch (Exception ex) + { + Console.WriteLine("An error occurred while trying to get the physical core count: " + ex.Message); + } + + return coreCount; + } } }