[gegl] gegl-parallel: avoid extraneous threads when distributing range/area



commit 4873b164f90a3e87ece01cfa6fe2e151b57c5e5c
Author: Ell <ell_se yahoo com>
Date:   Mon Nov 11 20:05:59 2019 +0200

    gegl-parallel: avoid extraneous threads when distributing range/area
    
    In gegl_parallel_distribute_{range,area}(), make sure not to use
    more threads than there are pixels to process (or, in the case of
    gegl_parallel_distribute_area(), rows/columns to process), so that
    each thread has at least some work to do.  Since thread cost is now
    calculated dynamically, low thread-cost values could result in too
    many threads being used, some of which would process an empty area.
    This could lead to bugs, on top of being inefficient.

 gegl/gegl-parallel.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)
---
diff --git a/gegl/gegl-parallel.c b/gegl/gegl-parallel.c
index 8703b3de1..dc1ab4582 100644
--- a/gegl/gegl-parallel.c
+++ b/gegl/gegl-parallel.c
@@ -252,6 +252,8 @@ gegl_parallel_distribute_range (gsize                           size,
     size,
     thread_cost);
 
+  n_threads = MIN (n_threads, size);
+
   if (n_threads == 1)
     {
       func (0, size, user_data);
@@ -333,23 +335,37 @@ gegl_parallel_distribute_area (const GeglRectangle            *area,
   if (area->width <= 0 || area->height <= 0)
     return;
 
+  if (split_strategy == GEGL_SPLIT_STRATEGY_AUTO)
+    {
+      if (area->width > area->height)
+        split_strategy = GEGL_SPLIT_STRATEGY_VERTICAL;
+      else
+        split_strategy = GEGL_SPLIT_STRATEGY_HORIZONTAL;
+    }
+
   n_threads = gegl_parallel_distribute_get_optimal_n_threads (
     (gdouble) area->width * (gdouble) area->height,
     thread_cost);
 
-  if (n_threads == 1)
+  switch (split_strategy)
     {
-      func (area, user_data);
+    case GEGL_SPLIT_STRATEGY_HORIZONTAL:
+      n_threads = MIN (n_threads, area->height);
+      break;
 
-      return;
+    case GEGL_SPLIT_STRATEGY_VERTICAL:
+      n_threads = MIN (n_threads, area->width);
+      break;
+
+    default:
+      g_return_if_reached ();
     }
 
-  if (split_strategy == GEGL_SPLIT_STRATEGY_AUTO)
+  if (n_threads == 1)
     {
-      if (area->width > area->height)
-        split_strategy = GEGL_SPLIT_STRATEGY_VERTICAL;
-      else
-        split_strategy = GEGL_SPLIT_STRATEGY_HORIZONTAL;
+      func (area, user_data);
+
+      return;
     }
 
   data.area           = area;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]