[Bf-blender-cvs] [751573c] master: Fix T50034: Blender changes processor affinity unauthorized

Sergey Sharybin noreply at git.blender.org
Tue Nov 22 16:04:12 CET 2016


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. */




More information about the Bf-blender-cvs mailing list