[gegl/wip/threaded-dup-input: 2/4] operation, transform: use separate input buffers for different threads
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/wip/threaded-dup-input: 2/4] operation, transform: use separate input buffers for different threads
- Date: Wed, 13 Dec 2017 09:08:33 +0000 (UTC)
commit 7318fa3ba1c4710e0a469fbe60ddf5f8dd726821
Author: Ell <ell_se yahoo com>
Date: Wed Dec 13 03:24:28 2017 -0500
operation, transform: use separate input buffers for different threads
Use gegl_operation_context_dup_input_maybe_copy(), added in the
previous commit, in GimpOperationFilter, GimpOperationComposer,
GimpOperationComposer3, and OpTransform (however, *not* in the
corresponding point ops), to (potentially) create a separate copy
of the input buffer for each thread, to avoid lock contention over
the input buffer's tile-storage lock. Use the input buffer
directly only for the first chunk, which is processed by the caller
thread.
This significantly improves performance of operations that randomly
access the input buffer (e.g., using a sampler), and seems not to
pessimize operations with a more regular access pattern (e.g.,
using an iterator, or scan rows).
gegl/operation/gegl-operation-composer.c | 21 ++++++++++++++++-----
gegl/operation/gegl-operation-composer3.c | 22 ++++++++++++++++------
gegl/operation/gegl-operation-filter.c | 20 +++++++++++++++-----
operations/transform/transform-core.c | 21 +++++++++++++++------
4 files changed, 62 insertions(+), 22 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-composer.c b/gegl/operation/gegl-operation-composer.c
index b67a745..c971baa 100644
--- a/gegl/operation/gegl-operation-composer.c
+++ b/gegl/operation/gegl-operation-composer.c
@@ -101,7 +101,7 @@ typedef struct ThreadData
{
GeglOperationComposerClass *klass;
GeglOperation *operation;
- GeglBuffer *input;
+ GeglOperationContext *context;
GeglBuffer *aux;
GeglBuffer *output;
gint *pending;
@@ -110,12 +110,23 @@ typedef struct ThreadData
GeglRectangle roi;
} ThreadData;
-static void thread_process (gpointer thread_data, gpointer unused)
+static void thread_process (gpointer thread_data, gpointer input)
{
ThreadData *data = thread_data;
+
+ if (! input)
+ {
+ input = gegl_operation_context_dup_input_maybe_copy (data->context,
+ "input", &data->roi);
+ }
+
if (!data->klass->process (data->operation,
- data->input, data->aux, data->output, &data->roi, data->level))
+ input, data->aux, data->output,
+ &data->roi, data->level))
data->success = FALSE;
+
+ g_object_unref (input);
+
g_atomic_int_add (data->pending, -1);
}
@@ -197,7 +208,7 @@ gegl_operation_composer_process (GeglOperation *operation,
{
thread_data[i].klass = klass;
thread_data[i].operation = operation;
- thread_data[i].input = input;
+ thread_data[i].context = context;
thread_data[i].aux = aux;
thread_data[i].output = output;
thread_data[i].pending = &pending;
@@ -207,7 +218,7 @@ gegl_operation_composer_process (GeglOperation *operation,
for (gint i = 1; i < threads; i++)
g_thread_pool_push (pool, &thread_data[i], NULL);
- thread_process (&thread_data[0], NULL);
+ thread_process (&thread_data[0], g_object_ref (input));
while (g_atomic_int_get (&pending)) {};
diff --git a/gegl/operation/gegl-operation-composer3.c b/gegl/operation/gegl-operation-composer3.c
index 5e660e7..9fbbfbc 100644
--- a/gegl/operation/gegl-operation-composer3.c
+++ b/gegl/operation/gegl-operation-composer3.c
@@ -110,7 +110,7 @@ typedef struct ThreadData
{
GeglOperationComposer3Class *klass;
GeglOperation *operation;
- GeglBuffer *input;
+ GeglOperationContext *context;
GeglBuffer *aux;
GeglBuffer *aux2;
GeglBuffer *output;
@@ -120,13 +120,23 @@ typedef struct ThreadData
GeglRectangle roi;
} ThreadData;
-static void thread_process (gpointer thread_data, gpointer unused)
+static void thread_process (gpointer thread_data, gpointer input)
{
ThreadData *data = thread_data;
+
+ if (! input)
+ {
+ input = gegl_operation_context_dup_input_maybe_copy (data->context,
+ "input", &data->roi);
+ }
+
if (!data->klass->process (data->operation,
- data->input, data->aux, data->aux2,
- data->output, &data->roi, data->level))
+ input, data->aux, data->aux2,
+ data->output, &data->roi, data->level))
data->success = FALSE;
+
+ g_object_unref (input);
+
g_atomic_int_add (data->pending, -1);
}
@@ -219,7 +229,7 @@ gegl_operation_composer3_process (GeglOperation *operation,
{
thread_data[i].klass = klass;
thread_data[i].operation = operation;
- thread_data[i].input = input;
+ thread_data[i].context = context;
thread_data[i].aux = aux;
thread_data[i].aux2 = aux2;
thread_data[i].output = output;
@@ -230,7 +240,7 @@ gegl_operation_composer3_process (GeglOperation *operation,
for (gint i = 1; i < threads; i++)
g_thread_pool_push (pool, &thread_data[i], NULL);
- thread_process (&thread_data[0], NULL);
+ thread_process (&thread_data[0], g_object_ref (input));
while (g_atomic_int_get (&pending)) {};
diff --git a/gegl/operation/gegl-operation-filter.c b/gegl/operation/gegl-operation-filter.c
index 2d26610..5c63381 100644
--- a/gegl/operation/gegl-operation-filter.c
+++ b/gegl/operation/gegl-operation-filter.c
@@ -109,7 +109,7 @@ typedef struct ThreadData
{
GeglOperationFilterClass *klass;
GeglOperation *operation;
- GeglBuffer *input;
+ GeglOperationContext *context;
GeglBuffer *output;
gint *pending;
gint level;
@@ -117,12 +117,22 @@ typedef struct ThreadData
GeglRectangle roi;
} ThreadData;
-static void thread_process (gpointer thread_data, gpointer unused)
+static void thread_process (gpointer thread_data, gpointer input)
{
ThreadData *data = thread_data;
+
+ if (! input)
+ {
+ input = gegl_operation_context_dup_input_maybe_copy (data->context,
+ "input", &data->roi);
+ }
+
if (!data->klass->process (data->operation,
- data->input, data->output, &data->roi, data->level))
+ input, data->output, &data->roi, data->level))
data->success = FALSE;
+
+ g_object_unref (input);
+
g_atomic_int_add (data->pending, -1);
}
@@ -219,7 +229,7 @@ gegl_operation_filter_process (GeglOperation *operation,
{
thread_data[i].klass = klass;
thread_data[i].operation = operation;
- thread_data[i].input = input;
+ thread_data[i].context = context;
thread_data[i].output = output;
thread_data[i].pending = &pending;
thread_data[i].level = level;
@@ -228,7 +238,7 @@ gegl_operation_filter_process (GeglOperation *operation,
for (gint i = 1; i < threads; i++)
g_thread_pool_push (pool, &thread_data[i], NULL);
- thread_process (&thread_data[0], NULL);
+ thread_process (&thread_data[0], g_object_ref (input));
while (g_atomic_int_get (&pending)) {};
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index e31ddd9..34c6606 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -749,7 +749,7 @@ typedef struct ThreadData
GeglOperation *operation;
- GeglBuffer *input;
+ GeglOperationContext *context;
GeglBuffer *output;
gint *pending;
GeglMatrix3 *matrix;
@@ -758,16 +758,25 @@ typedef struct ThreadData
GeglRectangle roi;
} ThreadData;
-static void thread_process (gpointer thread_data, gpointer unused)
+static void thread_process (gpointer thread_data, gpointer input)
{
ThreadData *data = thread_data;
+
+ if (! input)
+ {
+ input = gegl_operation_context_dup_input_maybe_copy (data->context,
+ "input", &data->roi);
+ }
+
data->func (data->operation,
data->output,
- data->input,
+ input,
data->matrix,
&data->roi,
data->level);
- data->success = FALSE;
+
+ g_object_unref (input);
+
g_atomic_int_add (data->pending, -1);
}
@@ -1255,7 +1264,7 @@ gegl_transform_process (GeglOperation *operation,
thread_data[i].func = func;
thread_data[i].matrix = &matrix;
thread_data[i].operation = operation;
- thread_data[i].input = input;
+ thread_data[i].context = context;
thread_data[i].output = output;
thread_data[i].pending = &pending;
thread_data[i].level = level;
@@ -1264,7 +1273,7 @@ gegl_transform_process (GeglOperation *operation,
for (gint i = 1; i < threads; i++)
g_thread_pool_push (pool, &thread_data[i], NULL);
- thread_process (&thread_data[0], NULL);
+ thread_process (&thread_data[0], g_object_ref (input));
while (g_atomic_int_get (&pending)) {};
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]