From 128f8eda98ee10a18cc48d41f7fede0d89fe1159 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 19 May 2025 12:40:46 +1000 Subject: [PATCH] Bind threads to cores --- .../voxy/common/thread/ServiceThreadPool.java | 20 +++++++++++++++---- .../voxy/common/util/cpu/CpuLayout.java | 19 +++++++++++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/java/me/cortex/voxy/common/thread/ServiceThreadPool.java b/src/main/java/me/cortex/voxy/common/thread/ServiceThreadPool.java index 35c40d99..06e1d4dd 100644 --- a/src/main/java/me/cortex/voxy/common/thread/ServiceThreadPool.java +++ b/src/main/java/me/cortex/voxy/common/thread/ServiceThreadPool.java @@ -3,6 +3,7 @@ package me.cortex.voxy.common.thread; import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.util.Pair; import me.cortex.voxy.common.util.ThreadUtils; +import me.cortex.voxy.common.util.cpu.CpuLayout; import java.lang.invoke.VarHandle; import java.lang.management.ManagementFactory; @@ -32,11 +33,25 @@ public class ServiceThreadPool { } public ServiceThreadPool(int threadCount, int priority) { + if (CpuLayout.CORES.length-2 < threadCount) { + Logger.warn("The thread count over core count -2, performance degradation possible"); + } + this.threadGroup = new ThreadGroup("Service job workers"); this.workers = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { int threadId = i; - var worker = new Thread(this.threadGroup, ()->this.worker(threadId)); + var worker = new Thread(this.threadGroup, ()->{ + if (CpuLayout.CORES.length>3) { + //Set worker affinity if possible + CpuLayout.setThreadAffinity(CpuLayout.CORES[2 + (threadId % (CpuLayout.CORES.length - 2))]); + } + + ThreadUtils.SetSelfThreadPriorityWin32(ThreadUtils.WIN32_THREAD_PRIORITY_LOWEST); + //ThreadUtils.SetSelfThreadPriorityWin32(ThreadUtils.WIN32_THREAD_MODE_BACKGROUND_BEGIN); + + this.worker(threadId); + }); worker.setDaemon(false); worker.setName("Service worker #" + i); worker.setPriority(priority); @@ -133,9 +148,6 @@ public class ServiceThreadPool { } private void worker(int threadId) { - ThreadUtils.SetSelfThreadPriorityWin32(ThreadUtils.WIN32_THREAD_PRIORITY_LOWEST); - //ThreadUtils.SetSelfThreadPriorityWin32(ThreadUtils.WIN32_THREAD_MODE_BACKGROUND_BEGIN); - long[] seed = new long[]{1234342^(threadId*124987198651981L+215987981111L)}; int[] revolvingSelector = new int[1]; long[] logIO = new long[] {0, System.currentTimeMillis()}; diff --git a/src/main/java/me/cortex/voxy/common/util/cpu/CpuLayout.java b/src/main/java/me/cortex/voxy/common/util/cpu/CpuLayout.java index 8d32c6dd..77fa3bf6 100644 --- a/src/main/java/me/cortex/voxy/common/util/cpu/CpuLayout.java +++ b/src/main/java/me/cortex/voxy/common/util/cpu/CpuLayout.java @@ -64,6 +64,7 @@ public class CpuLayout { } res[i++] = new Core((!allSameClass)&&eclz==0, new Affinity(msk, core.groupMask[0].group)); } + sort(res); return res; } @@ -94,10 +95,25 @@ public class CpuLayout { } cores[i++] = new Core(core.getEfficiency()==0&&!allSameEfficiency, aff); } - + sort(cores); return cores; } + + private static void sort(Core[] cores) { + Arrays.sort(cores, (a,b)->{ + if (a.isEfficiency == b.isEfficiency) { + int c = Short.compareUnsigned(a.affinity.group, b.affinity.group); + if (c==0) { + return Long.compareUnsigned(a.affinity.msk, b.affinity.msk); + } + return c; + } else { + return a.isEfficiency?1:-1; + } + }); + } + public record Affinity(long msk, short group) {} public record Core(boolean isEfficiency, Affinity affinity) { @@ -115,6 +131,7 @@ public class CpuLayout { } public static void main(String[] args) throws InterruptedException { + System.err.println(Arrays.toString(CORES)); setThreadAffinity(CORES[0], CORES[1]); for (int i = 0; i < 20; i++) { int finalI = i;