Commit: 751573ce6fff547b6a53769245814bc2d3fed17f
Author: Sergey Sharybin
Date:   Tue Nov 22 16:03:16 2016 +0100
Branches: master
https://developer.blender.org/rB751573ce6fff547b6a53769245814bc2d3fed17f

Fix T50034: Blender changes processor affinity unauthorized

===================================================================

M       intern/cycles/util/util_system.cpp
M       intern/cycles/util/util_system.h
M       intern/cycles/util/util_task.cpp
M       intern/cycles/util/util_windows.cpp
M       intern/cycles/util/util_windows.h

===================================================================

diff --git a/intern/cycles/util/util_system.cpp 
b/intern/cycles/util/util_system.cpp
index d5fac9a..2c7abba 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -89,6 +89,20 @@ int system_cpu_thread_count()
        return count;
 }
 
+unsigned short system_cpu_process_groups(unsigned short max_groups,
+                                         unsigned short *grpups)
+{
+#ifdef _WIN32
+       unsigned short group_count = max_groups;
+       if(!GetProcessGroupAffinity(GetCurrentProcess(), &group_count, grpups)) 
{
+               return 0;
+       }
+       return group_count;
+#else
+       return 0;
+#endif
+}
+
 #if !defined(_WIN32) || defined(FREE_WINDOWS)
 static void __cpuid(int data[4], int selector)
 {
diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h
index 557aab6..ff61b26 100644
--- a/intern/cycles/util/util_system.h
+++ b/intern/cycles/util/util_system.h
@@ -30,6 +30,10 @@ int system_cpu_group_thread_count(int group);
 /* Get total number of threads in all groups. */
 int system_cpu_thread_count();
 
+/* Get current process groups. */
+unsigned short system_cpu_process_groups(unsigned short max_groups,
+                                         unsigned short *grpups);
+
 string system_cpu_brand_string();
 int system_cpu_bits();
 bool system_cpu_support_sse2();
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index 352ba81..0d1fed3 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -195,7 +195,8 @@ void TaskScheduler::init(int num_threads)
        if(users == 0) {
                do_exit = false;
 
-               if(num_threads == 0) {
+               const bool use_auto_threads = (num_threads == 0);
+               if(use_auto_threads) {
                        /* automatic number of threads */
                        num_threads = system_cpu_thread_count();
                }
@@ -204,7 +205,18 @@ void TaskScheduler::init(int num_threads)
                /* launch threads that will be waiting for work */
                threads.resize(num_threads);
 
-               int num_groups = system_cpu_group_count();
+               const int num_groups = system_cpu_group_count();
+               unsigned short num_process_groups;
+               vector<unsigned short> process_groups;
+               int current_group_threads;
+               if(num_groups > 1) {
+                       process_groups.resize(num_groups);
+                       num_process_groups = 
system_cpu_process_groups(num_groups, 
+                                                                      
&process_groups[0]);
+                       if(num_process_groups == 1) {
+                               current_group_threads = 
system_cpu_group_thread_count(process_groups[0]);
+                       }
+               }
                int thread_index = 0;
                for(int group = 0; group < num_groups; ++group) {
                        /* NOTE: That's not really efficient from threading 
point of view,
@@ -218,9 +230,25 @@ void TaskScheduler::init(int num_threads)
                                group_thread < num_group_threads && 
thread_index < threads.size();
                                ++group_thread, ++thread_index)
                        {
+                               /* NOTE: Thread group of -1 means we would not 
force thread affinity. */
+                               int thread_group;
+                               if(num_groups == 1) {
+                                       /* Use default affinity if there's only 
one CPU group in the system. */
+                                       thread_group = -1;
+                               }
+                               else if(use_auto_threads &&
+                                       num_process_groups == 1 &&
+                                               num_threads <= 
current_group_threads)
+                               {
+                                       /* If we fit into curent CPU group we 
also don't force any affinity. */
+                                       thread_group = -1;
+                               }
+                               else {
+                                       thread_group = group;
+                               }
                                threads[thread_index] = new 
thread(function_bind(&TaskScheduler::thread_run,
                                                                                
 thread_index + 1),
-                                                                  group);
+                                                                  
thread_group);
                        }
                }
        }
diff --git a/intern/cycles/util/util_windows.cpp 
b/intern/cycles/util/util_windows.cpp
index ee5b3fd..4de8483 100644
--- a/intern/cycles/util/util_windows.cpp
+++ b/intern/cycles/util/util_windows.cpp
@@ -28,6 +28,7 @@ CCL_NAMESPACE_BEGIN
 tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount;
 tGetActiveProcessorCount *GetActiveProcessorCount;
 tSetThreadGroupAffinity *SetThreadGroupAffinity;
+tGetProcessGroupAffinity *GetProcessGroupAffinity;
 #endif
 
 static WORD GetActiveProcessorGroupCount_stub()
@@ -50,6 +51,18 @@ static BOOL SetThreadGroupAffinity_stub(
        return TRUE;
 }
 
+static BOOL GetProcessGroupAffinity_stub(HANDLE hProcess,
+                                         PUSHORT GroupCount,
+                                         PUSHORT GroupArray)
+{
+       if(*GroupCount < 1) {
+               return FALSE;
+       }
+       *GroupCount = 1;
+       GroupArray[0] = 0;
+       return TRUE;
+}
+
 static bool supports_numa()
 {
 #ifndef _M_X64
@@ -72,6 +85,7 @@ void util_windows_init_numa_groups()
                GetActiveProcessorGroupCount = 
GetActiveProcessorGroupCount_stub;
                GetActiveProcessorCount = GetActiveProcessorCount_stub;
                SetThreadGroupAffinity = SetThreadGroupAffinity_stub;
+               GetProcessGroupAffinity = GetProcessGroupAffinity_stub;
                return;
        }
        HMODULE kernel = GetModuleHandleA("kernel32.dll");
@@ -79,6 +93,7 @@ void util_windows_init_numa_groups()
        READ_SYMBOL(GetActiveProcessorGroupCount);
        READ_SYMBOL(GetActiveProcessorCount);
        READ_SYMBOL(SetThreadGroupAffinity);
+       READ_SYMBOL(GetProcessGroupAffinity);
 #  undef READ_SUMBOL
 #endif
 }
diff --git a/intern/cycles/util/util_windows.h 
b/intern/cycles/util/util_windows.h
index ac61d53..7ea3e65 100644
--- a/intern/cycles/util/util_windows.h
+++ b/intern/cycles/util/util_windows.h
@@ -39,10 +39,14 @@ typedef DWORD tGetActiveProcessorCount(WORD GroupNumber);
 typedef BOOL tSetThreadGroupAffinity(HANDLE hThread,
                                      const GROUP_AFFINITY  *GroupAffinity,
                                      PGROUP_AFFINITY PreviousGroupAffinity);
+typedef BOOL tGetProcessGroupAffinity(HANDLE  hProcess,
+                                     PUSHORT GroupCount,
+                                     PUSHORT GroupArray);
 
 extern tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount;
 extern tGetActiveProcessorCount *GetActiveProcessorCount;
 extern tSetThreadGroupAffinity *SetThreadGroupAffinity;
+extern tGetProcessGroupAffinity *GetProcessGroupAffinity;
 #endif
 
 /* Make sure NUMA and processor groups API is initialized. */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to