Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-11-22 18:03:16 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-11-22 18:03:16 +0300
commit751573ce6fff547b6a53769245814bc2d3fed17f (patch)
treec7a48856b85986eac308b7f4afc3eaf747686fe2 /intern
parentcb694d6595c78767874baf021096cc217858c85b (diff)
Fix T50034: Blender changes processor affinity unauthorized
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/util/util_system.cpp14
-rw-r--r--intern/cycles/util/util_system.h4
-rw-r--r--intern/cycles/util/util_task.cpp34
-rw-r--r--intern/cycles/util/util_windows.cpp15
-rw-r--r--intern/cycles/util/util_windows.h4
5 files changed, 68 insertions, 3 deletions
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index d5fac9a0e34..2c7abbaacbb 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 557aab6cbae..ff61b260bed 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 352ba81c95a..0d1fed3ebbf 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 ee5b3fd73c0..4de8483564b 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 ac61d5348c3..7ea3e65c2c5 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. */