Fix T60145: Cycles resets manually set affinity
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 11 Jan 2019 16:55:36 +0000 (17:55 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 11 Jan 2019 16:55:36 +0000 (17:55 +0100)
This change brings back old original logic which was checking
whether worker threads do fit into an active CPU group. But
it does it a bit smarter now and is also checking affinity
within that group. This way Cycles will use all threads on a
Threadripper2 CPU if it's set to automatic number of threads,
but on another hand will not change affinity if user requested
16 threads and changed Blender affinity.

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

index cc2d701..a22bd25 100644 (file)
@@ -40,7 +40,7 @@ bool system_cpu_ensure_initialized()
 {
        static bool is_initialized = false;
        static bool result = false;
-       if (is_initialized) {
+       if(is_initialized) {
                return result;
        }
        is_initialized = true;
@@ -71,8 +71,8 @@ int system_cpu_thread_count()
 {
        const int num_nodes = system_cpu_num_numa_nodes();
        int num_threads = 0;
-       for (int node = 0; node < num_nodes; ++node) {
-               if (!system_cpu_is_numa_node_available(node)) {
+       for(int node = 0; node < num_nodes; ++node) {
+               if(!system_cpu_is_numa_node_available(node)) {
                        continue;
                }
                num_threads += system_cpu_num_numa_node_processors(node);
@@ -82,7 +82,7 @@ int system_cpu_thread_count()
 
 int system_cpu_num_numa_nodes()
 {
-       if (!system_cpu_ensure_initialized()) {
+       if(!system_cpu_ensure_initialized()) {
                /* Fallback to a single node with all the threads. */
                return 1;
        }
@@ -91,7 +91,7 @@ int system_cpu_num_numa_nodes()
 
 bool system_cpu_is_numa_node_available(int node)
 {
-       if (!system_cpu_ensure_initialized()) {
+       if(!system_cpu_ensure_initialized()) {
                return true;
        }
        return numaAPI_IsNodeAvailable(node);
@@ -99,7 +99,7 @@ bool system_cpu_is_numa_node_available(int node)
 
 int system_cpu_num_numa_node_processors(int node)
 {
-       if (!system_cpu_ensure_initialized()) {
+       if(!system_cpu_ensure_initialized()) {
                return system_cpu_thread_count_fallback();
        }
        return numaAPI_GetNumNodeProcessors(node);
@@ -107,12 +107,20 @@ int system_cpu_num_numa_node_processors(int node)
 
 bool system_cpu_run_thread_on_node(int node)
 {
-       if (!system_cpu_ensure_initialized()) {
+       if(!system_cpu_ensure_initialized()) {
                return true;
        }
        return numaAPI_RunThreadOnNode(node);
 }
 
+int system_cpu_num_active_group_processors()
+{
+       if(!system_cpu_ensure_initialized()) {
+               return system_cpu_thread_count_fallback();
+       }
+       return numaAPI_GetNumCurrentNodesProcessors();
+}
+
 #if !defined(_WIN32) || defined(FREE_WINDOWS)
 static void __cpuid(int data[4], int selector)
 {
index 15f69bc..0c001f1 100644 (file)
@@ -44,6 +44,10 @@ int system_cpu_num_numa_node_processors(int node);
  * Returns truth if affinity has successfully changed. */
 bool system_cpu_run_thread_on_node(int node);
 
+/* Number of processors within the current CPU group (or within active thread
+ * thread affinity). */
+int system_cpu_num_active_group_processors();
+
 string system_cpu_brand_string();
 int system_cpu_bits();
 bool system_cpu_support_sse2();
index 7e9f731..4241c4a 100644 (file)
@@ -228,9 +228,21 @@ int get_num_total_processors(const vector<int>& num_per_node_processors)
 void distribute_threads_on_nodes(const vector<thread*>& threads)
 {
        const int num_threads = threads.size();
-       /* TODO(sergey): Skip overriding affinity if threads fits into the current
-        * nodes/CPU group. This will allow user to tweak affinity for weird and
-        * wonderful reasons. */
+       const int num_active_group_processors =
+               system_cpu_num_active_group_processors();
+       VLOG(1) << "Detected " << num_active_group_processors << " processors "
+               << "in active group.";
+       if(num_active_group_processors >= num_threads) {
+               /* If the current thread is set up in a way that its affinity allows to
+                * use at least requested number of threads we do not explicitly set
+                * affinity to the worker therads.
+                * This way we allow users to manually edit affinity of the parent
+                * thread, and here we follow that affinity. This way it's possible to
+                * have two Cycles/Blender instances running manually set to a different
+                * dies on a CPU. */
+               VLOG(1) << "Not setting thread group affinity.";
+               return;
+       }
        vector<int> num_per_node_processors;
        get_per_node_num_processors(&num_per_node_processors);
        if(num_per_node_processors.size() == 0) {