[gegl] gegl/buffer: make shape and offset of sampler prefetch adaptive
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gegl/buffer: make shape and offset of sampler prefetch adaptive
- Date: Fri, 5 Jan 2018 01:21:46 +0000 (UTC)
commit f606e8f961c86da0e867ca4920ab77efbef89bcd
Author: Øyvind Kolås <pippin gimp org>
Date: Fri Jan 5 02:13:41 2018 +0100
gegl/buffer: make shape and offset of sampler prefetch adaptive
This makes reuse of prefetched data more likely, for the rotate test-case in
perf it doubles the throughput.
gegl/buffer/gegl-sampler.c | 97 ++++++++++----------------------------------
gegl/buffer/gegl-sampler.h | 23 ++++++++---
2 files changed, 39 insertions(+), 81 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index 972b1fe..6c7062c 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -254,89 +254,36 @@ GeglRectangle _gegl_sampler_compute_rectangle (GeglSampler *sampler,
GeglRectangle rectangle;
GeglSamplerLevel *level = &sampler->level[level_no];
- if (level->last_x || level->last_y)
- {
- gint x_delta = x - level->last_x;
- gint y_delta = y - level->last_y;
- gint max_delta_squared = 60 * 60;
-
- if (x_delta * x_delta < max_delta_squared &&
- y_delta * y_delta < max_delta_squared)
- {
- level->x_delta = level->x_delta * 0.99 + x_delta * 0.01;
- level->y_delta = level->y_delta * 0.99 + y_delta * 0.01;
- if (x_delta < 0) x_delta = -x_delta;
- if (y_delta < 0) y_delta = -y_delta;
- level->x_magnitude = level->x_magnitude * 0.99 + x_delta * 0.01;
- level->y_magnitude = level->y_magnitude * 0.99 + y_delta * 0.01;
- }
- }
- level->last_x = x;
- level->last_y = y;
-
rectangle.width = level->context_rect.width + 2;
rectangle.height = level->context_rect.height + 2;
+ /* grow in direction of prediction */
+ if (level->delta_x * level->delta_x >
+ level->delta_y * level->delta_y)
+ {
+ rectangle.width *= 2;
+ }
+ else
+ {
+ rectangle.height *= 2;
+ }
+
rectangle.x = x + level->context_rect.x;
rectangle.y = y + level->context_rect.y;
- /* grow area slightly, maybe getting a couple of extra
- hits out of cour cache
- */
- rectangle.x -= 2;
- rectangle.y -= 2;
- rectangle.width += 4;
- rectangle.height += 4;
-
-#if 0
- /* XXX: FIXME: grow cached area based on sampling pattern profiling
- * information, possibly with much bigger wins than the marginal wins the
- * increase in size by 2 in each dir does.
- */
-
-
- if (level->x_magnitude > 0.001 || level->y_magnitude > 0.001)
- {
- gfloat magnitude = sqrtf (level->x_magnitude * level->x_magnitude +
- level->y_magnitude * level->y_magnitude);
- gfloat new_magnitude;
-
- if (level->x_magnitude > level->y_magnitude)
- new_magnitude =
- 4 + 60 * (level->x_magnitude - level->y_magnitude) / level->x_magnitude;
- else
- new_magnitude =
- 4 + 60 * (level->y_magnitude - level->x_magnitude) / level->y_magnitude;
-
- rectangle.width =
- (level->x_magnitude / magnitude) * new_magnitude
- + level->context_rect.width + 2;
- rectangle.height =
- (level->y_magnitude / magnitude) * new_magnitude
- + level->context_rect.height + 2;
-
- /* todo: if both xmag and ymag are small - but similar in magnitude
- we should increase the size of the cache if it would fit, thus
- perhaps working better on small local non-linear access patterns
- */
-
+ rectangle.x -= 1;
+ rectangle.y -= 1;
+ rectangle.width += 2;
+ rectangle.height += 2;
- /* align rectangle corner we've likely entered with sampled pixel
- */
- if (level->x_delta >=0)
- rectangle.x = x + level->context_rect.x
- - (rectangle.width - level->context_rect.x)/10;
- else
- rectangle.x = x + level->context_rect.x
- - (rectangle.width - level->context_rect.width) * 9/10;
+ //fprintf (stderr, "{%f %f}", level->delta_x, level->delta_y);
- if (level->y_delta >=0)
- rectangle.y = y + level->context_rect.y
- - (rectangle.height - level->context_rect.y)/10;
- else
- rectangle.y = y + level->context_rect.y
- - (rectangle.height - level->context_rect.height) * 9/10;
- }
+#if 1
+ /* shift area based on prediction */
+ if (level->delta_x >=0.01)
+ rectangle.x -= rectangle.width * 0.3;
+ if (level->delta_y >=0.01)
+ rectangle.y -= rectangle.height * 0.3;
#endif
if (rectangle.width >= GEGL_SAMPLER_MAXIMUM_WIDTH)
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index f3464ff..efb9e08 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -20,6 +20,7 @@
#include <glib-object.h>
#include <babl/babl.h>
+#include <stdio.h>
G_BEGIN_DECLS
@@ -52,13 +53,10 @@ typedef struct GeglSamplerLevel
GeglRectangle context_rect;
gpointer sampler_buffer;
GeglRectangle sampler_rectangle;
-
gint last_x;
gint last_y;
- float x_delta;
- float y_delta;
- float x_magnitude;
- float y_magnitude;
+ float delta_x;
+ float delta_y;
} GeglSamplerLevel;
struct _GeglSampler
@@ -126,6 +124,7 @@ gegl_sampler_get_ptr (GeglSampler *sampler,
gint y,
GeglAbyssPolicy repeat_mode)
{
+ float delta_x, delta_y;
gint dx, dy, sof;
guchar *buffer_ptr;
@@ -137,7 +136,8 @@ gegl_sampler_get_ptr (GeglSampler *sampler,
(y + level->context_rect.y + level->context_rect.height >
level->sampler_rectangle.y + level->sampler_rectangle.height))
{
- level->sampler_rectangle = _gegl_sampler_compute_rectangle (sampler, x, y, 0);
+ level->sampler_rectangle =
+ _gegl_sampler_compute_rectangle (sampler, x, y, 0);
gegl_buffer_get (sampler->buffer,
&level->sampler_rectangle,
@@ -146,6 +146,10 @@ gegl_sampler_get_ptr (GeglSampler *sampler,
level->sampler_buffer,
GEGL_SAMPLER_MAXIMUM_WIDTH * GEGL_SAMPLER_BPP,
repeat_mode);
+ level->last_x = x;
+ level->last_y = y;
+ level->delta_x = 0;
+ level->delta_y = 0;
}
dx = x - level->sampler_rectangle.x;
@@ -153,6 +157,13 @@ gegl_sampler_get_ptr (GeglSampler *sampler,
sof = (dx + dy * GEGL_SAMPLER_MAXIMUM_WIDTH) * GEGL_SAMPLER_BPP;
buffer_ptr = (guchar *) level->sampler_buffer;
+ delta_x = level->last_x - x;
+ delta_y = level->last_y - y;
+ level->last_x = x;
+ level->last_y = y;
+ level->delta_x = (level->delta_x + delta_x) / 2;
+ level->delta_y = (level->delta_y + delta_y) / 2;
+
return (gfloat *) (buffer_ptr + sof);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]