[gegl] Added general caching floating point lookup table code.
- From: Øyvind Kolås <ok src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gegl] Added general caching floating point lookup table code.
- Date: Thu, 3 Dec 2009 12:25:06 +0000 (UTC)
commit a7e87a3c0409ea32f933b55c0678606ad03fa322
Author: �yvind Kolås <pippin gimp org>
Date: Thu Dec 3 12:21:50 2009 +0000
Added general caching floating point lookup table code.
examples/float-lookup.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++
gegl/gegl-types.h | 1 +
gegl/gegl-utils.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 158 insertions(+), 0 deletions(-)
---
diff --git a/examples/float-lookup.c b/examples/float-lookup.c
new file mode 100644
index 0000000..e554ee3
--- /dev/null
+++ b/examples/float-lookup.c
@@ -0,0 +1,78 @@
+#include <gegl.h>
+#include <gegl/gegl-utils.h>
+#include <math.h>
+
+static gfloat wrapped_sqrt (gfloat in,
+ gpointer data) /* we could have used the user data */
+{
+ return sqrt (in);
+}
+
+static gfloat passthrough (gfloat in, gpointer data)
+{
+ return in;
+}
+
+glong gegl_ticks (void);
+
+static inline int gegl_float_16_indext (float f)
+{
+ union
+ {
+ float f;
+ unsigned int i;
+ unsigned short s[2];
+ } u;
+ u.f = f;
+ return u.s[1];
+}
+
+
+
+gint main (int argc, gchar **argv)
+{
+ gfloat val;
+ gfloat foo;
+ gdouble sum = 0;
+ gint count=0;
+ GeglLookup *lookup;
+ gint ticks;
+
+ lookup = gegl_lookup_new (wrapped_sqrt, NULL);
+ ticks = gegl_ticks ();
+ for (val = 0; val < 1.0; val+=0.0000001)
+ foo = gegl_lookup (lookup, val);
+ ticks = gegl_ticks ()-ticks;
+ g_print ("First run: %i\n", ticks);
+
+ ticks = gegl_ticks ();
+ for (val = 0; val < 1.0; val+=0.0000001)
+ foo = gegl_lookup (lookup, val);
+ ticks = gegl_ticks ()-ticks;
+ g_print ("Second run: %i\n", ticks);
+
+ ticks = gegl_ticks ();
+ for (val = 0; val < 1.0; val+=0.0000001)
+ foo = gegl_lookup (lookup, val);
+ ticks = gegl_ticks ()-ticks;
+ g_print ("Third run: %i\n", ticks);
+
+
+ ticks = gegl_ticks ();
+ for (val = 0; val < 1.0; val+=0.0000001)
+ foo = sqrt (val);
+ ticks = gegl_ticks ()-ticks;
+ g_print ("Just sqrt: %i\n", ticks);
+ gegl_lookup_free (lookup);
+
+ {
+ /* stack allocated */
+ GeglLookup lookup = {passthrough, NULL, };
+ for (val = 0.0, sum=0.0, count=0; val < 1.0; val+=0.000001, count++)
+ sum += fabs (val-gegl_lookup (&lookup, val));
+ g_printf ("Average error in range 0.0-1.0: %f\n", sum/count);
+ foo = sqrt (val);
+ }
+
+ return 0;
+}
diff --git a/gegl/gegl-types.h b/gegl/gegl-types.h
index f42e6ca..935baa5 100644
--- a/gegl/gegl-types.h
+++ b/gegl/gegl-types.h
@@ -64,6 +64,7 @@ GType gegl_processor_get_type (void) G_GNUC_CONST;
#define GEGL_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_PROCESSOR, GeglProcessor))
#define GEGL_IS_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_PROCESSOR))
+typedef struct _GeglLookup GeglLookup;
G_END_DECLS
diff --git a/gegl/gegl-utils.h b/gegl/gegl-utils.h
index 886984d..eb3b435 100644
--- a/gegl/gegl-utils.h
+++ b/gegl/gegl-utils.h
@@ -203,6 +203,85 @@ gint _gegl_float_epsilon_equal (float v1,
float v2);
+typedef gfloat (GeglLookupFunction) (float, gpointer data);
+
+GeglLookup *gegl_lookup_new (GeglLookupFunction *function,
+ gpointer data);
+void gegl_lookup_free (GeglLookup *lookup);
+
+#define INDEX_SHIFT 14 /*
+ Valid values here are:
+ value tablesize average error
+ 16 5108 0.001298
+ 15 10316 0.000649
+ 14 20432 0.000324
+ */
+
+#if INDEX_SHIFT == 16
+
+#define INDEX_START_POSITIVE 13702
+#define INDEX_END_POSITIVE 16256
+#define INDEX_START_NEGATIVE 46470
+#define INDEX_END_NEGATIVE 49024
+
+#elif INDEX_SHIFT == 15
+
+#define INDEX_START_POSITIVE 27404
+#define INDEX_END_POSITIVE 32512
+#define INDEX_START_NEGATIVE 92940
+#define INDEX_END_NEGATIVE 98048
+
+#elif INDEX_SHIFT == 14
+
+#define INDEX_START_POSITIVE 54808
+#define INDEX_END_POSITIVE 65024
+#define INDEX_START_NEGATIVE 185880
+#define INDEX_END_NEGATIVE 196096
+
+#endif
+
+#define INDEX_SUM_POSITIVE (INDEX_END_POSITIVE-INDEX_START_POSITIVE)
+#define INDEX_SUM_NEGATIVE (INDEX_END_NEGATIVE-INDEX_START_NEGATIVE)
+#define INDEX_SUM (INDEX_SUM_POSITIVE+INDEX_SUM_NEGATIVE)
+
+typedef struct _GeglLookup
+{
+ GeglLookupFunction *function; /* the lookup function to execute */
+ gpointer data;
+ guint32 bitmask[(INDEX_SUM+31)/32];
+ gfloat table[INDEX_SUM];
+} _GeglLookup;
+
+static inline gfloat
+gegl_lookup (GeglLookup *lookup,
+ gfloat number)
+{
+ union
+ {
+ float f;
+ guint32 i;
+ } u;
+ guint index;
+
+ u.f = number;
+ index = u.i >> INDEX_SHIFT;
+ if (index > INDEX_START_POSITIVE && index < INDEX_END_POSITIVE)
+ index = index-INDEX_START_POSITIVE;
+ else if (index > INDEX_START_NEGATIVE && index < INDEX_END_NEGATIVE)
+ index = index-INDEX_START_NEGATIVE+INDEX_SUM_POSITIVE;
+ else
+ return lookup->function (number, lookup->data);
+
+ g_assert (index >= 0 && index < INDEX_SUM);
+
+ if (!(lookup->bitmask[index/32] & (1<<(index & 31))))
+ {
+ lookup->table[index]= lookup->function (number, lookup->data);
+ lookup->bitmask[index/32] |= (1<<(index & 31));
+ }
+ return lookup->table[index];
+}
+
G_END_DECLS
#endif /* __GEGL_UTILS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]