[Pixman] [PATCH 4/5] test: Switch to the new PRNG instead of old LCG

Siarhei Siamashka siarhei.siamashka at gmail.com
Sun Nov 25 04:08:56 PST 2012


Wallclock time for running pixman "make check" (compile time not included):

----------------------------+----------------+-----------------------------+
                            | old PRNG (LCG) |   new PRNG (Bob Jenkins)    |
       Processor type       +----------------+------------+----------------+
                            |    gcc 4.5     |  gcc 4.5   | gcc 4.7 (simd) |
----------------------------+----------------+------------+----------------+
quad Intel Core i7  @2.8GHz |    0m49.494s   |  0m43.722s |    0m37.560s   |
dual ARM Cortex-A15 @1.7GHz |     5m8.465s   |  4m37.375s |    3m45.819s   |
     IBM Cell PPU   @3.2GHz |    23m0.821s   | 20m38.316s |   16m37.513s   |
----------------------------+----------------+------------+----------------+

But some tests got a particularly large boost. For example benchmarking and
profiling blitters-test on Core i7:

=== before ===

$ time ./blitters-test

real    0m10.907s
user    0m55.650s
sys     0m0.000s

  70.45%  blitters-test  blitters-test       [.] create_random_image
  15.81%  blitters-test  blitters-test       [.] compute_crc32_for_image_internal
   2.26%  blitters-test  blitters-test       [.] _pixman_implementation_lookup_composite
   1.07%  blitters-test  libc-2.15.so        [.] _int_free
   0.89%  blitters-test  libc-2.15.so        [.] malloc_consolidate
   0.87%  blitters-test  libc-2.15.so        [.] _int_malloc
   0.75%  blitters-test  blitters-test       [.] combine_conjoint_general_u
   0.61%  blitters-test  blitters-test       [.] combine_disjoint_general_u
   0.40%  blitters-test  blitters-test       [.] test_composite
   0.31%  blitters-test  libc-2.15.so        [.] _int_memalign
   0.31%  blitters-test  blitters-test       [.] _pixman_bits_image_setup_accessors
   0.28%  blitters-test  libc-2.15.so        [.] malloc

=== after ===

$ time ./blitters-test

real    0m3.655s
user    0m20.550s
sys     0m0.000s

  41.77%  blitters-test.n  blitters-test.new  [.] compute_crc32_for_image_internal
  15.77%  blitters-test.n  blitters-test.new  [.] prng_randmemset_r
   6.15%  blitters-test.n  blitters-test.new  [.] _pixman_implementation_lookup_composite
   3.09%  blitters-test.n  libc-2.15.so       [.] _int_free
   2.68%  blitters-test.n  libc-2.15.so       [.] malloc_consolidate
   2.39%  blitters-test.n  libc-2.15.so       [.] _int_malloc
   2.27%  blitters-test.n  blitters-test.new  [.] create_random_image
   2.22%  blitters-test.n  blitters-test.new  [.] combine_conjoint_general_u
   1.52%  blitters-test.n  blitters-test.new  [.] combine_disjoint_general_u
   1.40%  blitters-test.n  blitters-test.new  [.] test_composite
   1.02%  blitters-test.n  blitters-test.new  [.] prng_srand_r
   1.00%  blitters-test.n  blitters-test.new  [.] _pixman_image_validate
   0.96%  blitters-test.n  blitters-test.new  [.] _pixman_bits_image_setup_accessors
   0.90%  blitters-test.n  libc-2.15.so       [.] malloc
---
 demos/Makefile.am           |    3 ++-
 test/affine-test.c          |   13 +++++--------
 test/alpha-loop.c           |   11 ++++++++---
 test/alphamap.c             |    2 ++
 test/blitters-test.c        |   16 +++++-----------
 test/composite-traps-test.c |    2 +-
 test/glyph-test.c           |   10 ++--------
 test/region-contains-test.c |    2 +-
 test/region-test.c          |    2 ++
 test/rotate-test.c          |    6 ++----
 test/scaling-helpers-test.c |    1 +
 test/scaling-test.c         |   17 ++++++-----------
 test/utils.c                |    9 ++++-----
 test/utils.h                |   40 ++++++++++++++++++++++++----------------
 14 files changed, 65 insertions(+), 69 deletions(-)

diff --git a/demos/Makefile.am b/demos/Makefile.am
index ffb7a6b..9e9db81 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -6,7 +6,8 @@ AM_LDFLAGS = $(OPENMP_CFLAGS)
 LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS)
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(GTK_CFLAGS) $(PNG_CFLAGS)
 
-GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h
+GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h \
+            ../test/utils-prng.c ../test/utils-prng.h
 
 DEMOS =				\
 	clip-test		\
diff --git a/test/affine-test.c b/test/affine-test.c
index d94023b..fc2e05b 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -77,11 +77,8 @@ test_composite (int      testnum,
     srcbuf = (uint32_t *)malloc (src_stride * src_height);
     dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
 
-    for (i = 0; i < src_stride * src_height; i++)
-	*((uint8_t *)srcbuf + i) = prng_rand_n (256);
-
-    for (i = 0; i < dst_stride * dst_height; i++)
-	*((uint8_t *)dstbuf + i) = prng_rand_n (256);
+    prng_randmemset (srcbuf, src_stride * src_height, 0);
+    prng_randmemset (dstbuf, dst_stride * dst_height, 0);
 
     src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ?
                               PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
@@ -310,11 +307,11 @@ test_composite (int      testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x344413F0
+#define CHECKSUM 0x97097336
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0xC8181A76
+#define CHECKSUM 0x31D2DC21
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0xD672A457
+#define CHECKSUM 0x8B925154
 #else
 #define CHECKSUM 0x00000000
 #endif
diff --git a/test/alpha-loop.c b/test/alpha-loop.c
index e4d90a9..eca7615 100644
--- a/test/alpha-loop.c
+++ b/test/alpha-loop.c
@@ -8,9 +8,14 @@
 int
 main (int argc, char **argv)
 {
-    uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
-    uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
-    uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    uint8_t *alpha;
+    uint32_t *src, *dest;
+
+    prng_srand (0);
+
+    alpha = make_random_bytes (WIDTH * HEIGHT);
+    src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
 
     pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
     pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
diff --git a/test/alphamap.c b/test/alphamap.c
index 0c5757e..1a6fca5 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -307,6 +307,8 @@ main (int argc, char **argv)
 {
     int i, j, a, b, x, y;
 
+    prng_srand (0);
+
     for (i = 0; i < ARRAY_LENGTH (formats); ++i)
     {
 	for (j = 0; j < ARRAY_LENGTH (formats); ++j)
diff --git a/test/blitters-test.c b/test/blitters-test.c
index b0115d4..9bde99c 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -25,7 +25,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
 		     int                   max_extra_stride,
 		     pixman_format_code_t *used_fmt)
 {
-    int n = 0, i, width, height, stride;
+    int n = 0, width, height, stride;
     pixman_format_code_t fmt;
     uint32_t *buf;
     pixman_image_t *img;
@@ -46,15 +46,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
     /* do the allocation */
     buf = aligned_malloc (64, stride * height);
 
-    /* initialize image with random data */
-    for (i = 0; i < stride * height; i++)
-    {
-	/* generation is biased to having more 0 or 255 bytes as
-	 * they are more likely to be special-cased in code
-	 */
-	*((uint8_t *)buf + i) = prng_rand_n (4) ? prng_rand_n (256) :
-	    (prng_rand_n (2) ? 0 : 255);
-    }
+    prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
 
     img = pixman_image_create_bits (fmt, width, height, buf, stride);
 
@@ -390,6 +382,8 @@ main (int argc, const char *argv[])
 {
     int i;
 
+    prng_srand (0);
+
     for (i = 1; i <= 8; i++)
     {
 	initialize_palette (&(rgb_palette[i]), i, TRUE);
@@ -397,6 +391,6 @@ main (int argc, const char *argv[])
     }
 
     return fuzzer_test_main("blitters", 2000000,
-			    0x46136E0A,
+			    0xD8265D5E,
 			    test_composite, argc, argv);
 }
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index efb3c30..5a4a921 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -251,6 +251,6 @@ test_composite (int      testnum,
 int
 main (int argc, const char *argv[])
 {
-    return fuzzer_test_main("composite traps", 40000, 0x33BFAA55,
+    return fuzzer_test_main("composite traps", 40000, 0x749BCC57,
 			    test_composite, argc, argv);
 }
diff --git a/test/glyph-test.c b/test/glyph-test.c
index 2fcc69c..7edb3be 100644
--- a/test/glyph-test.c
+++ b/test/glyph-test.c
@@ -153,14 +153,8 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
     }
     else
     {
-	uint8_t *d8;
-
 	data = malloc (stride * height);
-
-	d8 = (uint8_t *)data;
-	for (i = 0; i < height * stride; ++i)
-	    d8[i] = prng_rand_n (256);
-
+	prng_randmemset (data, height * stride, 0);
 	destroy = destroy_malloced;
     }
 
@@ -333,6 +327,6 @@ int
 main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("glyph", 30000,	
-			     0x79E74996,
+			     0xFA478A79,
 			     test_glyphs, argc, argv);
 }
diff --git a/test/region-contains-test.c b/test/region-contains-test.c
index aca24ad..c757347 100644
--- a/test/region-contains-test.c
+++ b/test/region-contains-test.c
@@ -163,7 +163,7 @@ main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("region_contains",
 			     1000000,
-			     0xD2BF8C73,
+			     0x548E0F3F,
 			     test_region_contains_rectangle,
 			     argc, argv);
 }
diff --git a/test/region-test.c b/test/region-test.c
index 87010f7..bfc219b 100644
--- a/test/region-test.c
+++ b/test/region-test.c
@@ -32,6 +32,8 @@ main ()
 	0xffff
     };
 
+    prng_srand (0);
+
     /* This used to go into an infinite loop before pixman-region.c
      * was fixed to not use explict "short" variables
      */
diff --git a/test/rotate-test.c b/test/rotate-test.c
index 0fe9301..9d2a620 100644
--- a/test/rotate-test.c
+++ b/test/rotate-test.c
@@ -63,10 +63,8 @@ make_image (void)
     pixman_format_code_t format = RANDOM_FORMAT();
     uint32_t *bytes = malloc (WIDTH * HEIGHT * 4);
     pixman_image_t *image;
-    int i;
 
-    for (i = 0; i < WIDTH * HEIGHT * 4; ++i)
-	((uint8_t *)bytes)[i] = prng_rand_n (256);
+    prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0);
 
     image = pixman_image_create_bits (
 	format, WIDTH, HEIGHT, bytes, WIDTH * 4);
@@ -108,6 +106,6 @@ int
 main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("rotate", 15000,
-			     0x5236FD9F,
+			     0xECF5E426,
 			     test_transform, argc, argv);
 }
diff --git a/test/scaling-helpers-test.c b/test/scaling-helpers-test.c
index a706020..2685ae1 100644
--- a/test/scaling-helpers-test.c
+++ b/test/scaling-helpers-test.c
@@ -52,6 +52,7 @@ int
 main (void)
 {
     int i;
+    prng_srand (0);
     for (i = 0; i < 10000; i++)
     {
 	int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1;
diff --git a/test/scaling-test.c b/test/scaling-test.c
index cfe9b52..44f851c 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -140,14 +140,9 @@ test_composite (int      testnum,
     maskbuf = (uint32_t *)malloc (mask_stride * mask_height);
     dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
 
-    for (i = 0; i < src_stride * src_height; i++)
-	*((uint8_t *)srcbuf + i) = prng_rand_n (256);
-
-    for (i = 0; i < mask_stride * mask_height; i++)
-	*((uint8_t *)maskbuf + i) = prng_rand_n (256);
-
-    for (i = 0; i < dst_stride * dst_height; i++)
-	*((uint8_t *)dstbuf + i) = prng_rand_n (256);
+    prng_randmemset (srcbuf, src_stride * src_height, 0);
+    prng_randmemset (maskbuf, mask_stride * mask_height, 0);
+    prng_randmemset (dstbuf, dst_stride * dst_height, 0);
 
     src_fmt = get_format (src_bpp);
     dst_fmt = get_format (dst_bpp);
@@ -380,11 +375,11 @@ test_composite (int      testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x107B67ED
+#define CHECKSUM 0x9096E6B6
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x30EC0CF0
+#define CHECKSUM 0xCE8EC6BA
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x87B496BC
+#define CHECKSUM 0xAB1D39BE
 #else
 #define CHECKSUM 0x00000000
 #endif
diff --git a/test/utils.c b/test/utils.c
index c82ba2b..dd0e556 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -27,10 +27,11 @@
 #include <png.h>
 #endif
 
-/* Random number seed
+/* Random number generator state
  */
 
-uint32_t prng_seed;
+prng_t prng_state_data;
+prng_t *prng_state;
 
 /*----------------------------------------------------------------------------*\
  *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
@@ -423,13 +424,11 @@ uint8_t *
 make_random_bytes (int n_bytes)
 {
     uint8_t *bytes = fence_malloc (n_bytes);
-    int i;
 
     if (!bytes)
 	return NULL;
 
-    for (i = 0; i < n_bytes; ++i)
-	bytes[i] = prng_rand () & 0xff;
+    prng_randmemset (bytes, n_bytes, 0);
 
     return bytes;
 }
diff --git a/test/utils.h b/test/utils.h
index ec4c4ad..f054887 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -4,6 +4,7 @@
 
 #include <assert.h>
 #include "pixman-private.h" /* For 'inline' definition */
+#include "utils-prng.h"
 
 #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
 
@@ -11,22 +12,32 @@
  * taken from POSIX.1-2001 example
  */
 
-extern uint32_t prng_seed;
+extern prng_t prng_state_data;
+extern prng_t *prng_state;
 #ifdef USE_OPENMP
-#pragma omp threadprivate(prng_seed)
+#pragma omp threadprivate(prng_state_data)
+#pragma omp threadprivate(prng_state)
 #endif
 
 static inline uint32_t
 prng_rand (void)
 {
-    prng_seed = prng_seed * 1103515245 + 12345;
-    return ((uint32_t)(prng_seed / 65536) % 32768);
+    return prng_rand_r (prng_state);
 }
 
 static inline void
 prng_srand (uint32_t seed)
 {
-    prng_seed = seed;
+    if (!prng_state)
+    {
+        /* Without setting a seed, PRNG does not work properly (is just
+         * returning zeros). So we only initialize the pointer here to
+         * make sure that 'prng_srand' is always called before any
+         * other 'prng_*' function. The wrongdoers violating this order
+         * will get a segfault. */
+        prng_state = &prng_state_data;
+    }
+    prng_srand_r (prng_state, seed);
 }
 
 static inline uint32_t
@@ -38,22 +49,19 @@ prng_rand_n (int max)
 static inline uint32_t
 prng_rand_N (int max)
 {
-    uint32_t lo = prng_rand ();
-    uint32_t hi = prng_rand () << 15;
-    return (lo | hi) % max;
+    return prng_rand () % max;
 }
 
 static inline uint32_t
 prng_rand_u32 (void)
 {
-    /* This uses the 10/11 most significant bits from the 3 lcg results
-     * (and mixes them with the low from the adjacent one).
-     */
-    uint32_t lo = prng_rand() >> -(32 - 15 - 11 * 2);
-    uint32_t mid = prng_rand() << (32 - 15 - 11 * 1);
-    uint32_t hi = prng_rand() << (32 - 15 - 11 * 0);
-
-    return (hi ^ mid ^ lo);
+    return prng_rand ();
+}
+
+static inline void
+prng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags)
+{
+    prng_randmemset_r (prng_state, buffer, size, flags);
 }
 
 /* CRC 32 computation
-- 
1.7.8.6



More information about the Pixman mailing list