From be3a30facca7bea048c5fd784910469c892da54d Mon Sep 17 00:00:00 2001 From: hailIulius Date: Wed, 27 Apr 2016 19:35:32 +0200 Subject: [PATCH] Use core affinity on windows to improve performance --- src/com/sheepit/client/Job.java | 1 + src/com/sheepit/client/os/Windows.java | 4 ++++ .../sheepit/client/os/windows/Kernel32Lib.java | 10 ++++++++++ src/com/sheepit/client/os/windows/WinProcess.java | 15 +++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/com/sheepit/client/Job.java b/src/com/sheepit/client/Job.java index 408a720..ac245f8 100644 --- a/src/com/sheepit/client/Job.java +++ b/src/com/sheepit/client/Job.java @@ -221,6 +221,7 @@ public class Job { Map new_env = new HashMap(); new_env.put("BLENDER_USER_CONFIG", config.workingDirectory.getAbsolutePath().replace("\\", "\\\\")); + new_env.put("CORES", Integer.toString(config.getNbCores())); for (String arg : command1) { switch (arg) { diff --git a/src/com/sheepit/client/os/Windows.java b/src/com/sheepit/client/os/Windows.java index c5a4bc7..08fd1bc 100644 --- a/src/com/sheepit/client/os/Windows.java +++ b/src/com/sheepit/client/os/Windows.java @@ -133,6 +133,10 @@ public class Windows extends OS { Process p = builder.start(); WinProcess wproc = new WinProcess(p); wproc.setPriority(WinProcess.PRIORITY_BELOW_NORMAL); + if (env != null) { + String cores = env.get("CORES"); + wproc.setAffinity(Integer.parseInt(cores)); + } return p; } diff --git a/src/com/sheepit/client/os/windows/Kernel32Lib.java b/src/com/sheepit/client/os/windows/Kernel32Lib.java index 51a30d4..c4863e9 100644 --- a/src/com/sheepit/client/os/windows/Kernel32Lib.java +++ b/src/com/sheepit/client/os/windows/Kernel32Lib.java @@ -21,6 +21,7 @@ import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.BaseTSD; +import com.sun.jna.platform.win32.BaseTSD.DWORD_PTR; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinNT; @@ -211,4 +212,13 @@ public interface Kernel32Lib extends Library { */ public int SetErrorMode(DWORD uMode); + /** + * See : https://msdn.microsoft.com/en-us/library/windows/desktop/ms686247%28v=vs.85%29.aspx + * + * @param hThread + * @param dwThreadAffinityMask + * @return If the function succeeds, the return value is the thread's previous affinity mask. + */ + public boolean SetProcessAffinityMask(HANDLE hProcess, DWORD_PTR dwProcessAffinityMask); + } diff --git a/src/com/sheepit/client/os/windows/WinProcess.java b/src/com/sheepit/client/os/windows/WinProcess.java index 67a8765..4c78e3e 100644 --- a/src/com/sheepit/client/os/windows/WinProcess.java +++ b/src/com/sheepit/client/os/windows/WinProcess.java @@ -26,6 +26,7 @@ import java.util.List; import com.sun.jna.Native; import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.BaseTSD.DWORD_PTR; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.Kernel32Util; import com.sun.jna.platform.win32.WinDef.DWORD; @@ -121,6 +122,20 @@ public class WinProcess { return this.kernel32lib.SetPriorityClass(this.handle, priority); } + public boolean setAffinity(int numberCores) { + // affects the process to a specific core/cpu, it will reduce the number of switch between core + // that way the machine will look "less busy" since default behavior for windows is to put 4 cores + // at 25% instead of 1 core at 100% but from the user point of view, it introduce lag. + if (numberCores > 0) { + long coreAffinity = 0; + for (int i = 0; i < numberCores; i++) { + coreAffinity |= 1L << i; + } + return this.kernel32lib.SetProcessAffinityMask(this.handle, new DWORD_PTR(coreAffinity)); + } + return false; + } + private void terminate() { Kernel32.INSTANCE.TerminateProcess(this.handle, 0); Kernel32.INSTANCE.CloseHandle(this.handle); // we are sure that the parent Process object is dead