forked from bartvdbraak/blender
Fix T50034: Blender changes processor affinity unauthorized
This commit is contained in:
parent
cb694d6595
commit
751573ce6f
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user