test: Switch to the new PRNG instead of old LCG

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
This commit is contained in:
Siarhei Siamashka 2012-11-25 02:50:35 +02:00
parent 309e66f047
commit b31a696263
14 changed files with 64 additions and 68 deletions

View File

@ -6,7 +6,8 @@ AM_LDFLAGS = $(OPENMP_CFLAGS)
LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS) 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) 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 = \ DEMOS = \
clip-test \ clip-test \

View File

@ -77,11 +77,8 @@ test_composite (int testnum,
srcbuf = (uint32_t *)malloc (src_stride * src_height); srcbuf = (uint32_t *)malloc (src_stride * src_height);
dstbuf = (uint32_t *)malloc (dst_stride * dst_height); dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
for (i = 0; i < src_stride * src_height; i++) prng_randmemset (srcbuf, src_stride * src_height, 0);
*((uint8_t *)srcbuf + i) = prng_rand_n (256); prng_randmemset (dstbuf, dst_stride * dst_height, 0);
for (i = 0; i < dst_stride * dst_height; i++)
*((uint8_t *)dstbuf + i) = prng_rand_n (256);
src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ? src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ?
PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
@ -310,11 +307,11 @@ test_composite (int testnum,
} }
#if BILINEAR_INTERPOLATION_BITS == 8 #if BILINEAR_INTERPOLATION_BITS == 8
#define CHECKSUM 0x344413F0 #define CHECKSUM 0x97097336
#elif BILINEAR_INTERPOLATION_BITS == 7 #elif BILINEAR_INTERPOLATION_BITS == 7
#define CHECKSUM 0xC8181A76 #define CHECKSUM 0x31D2DC21
#elif BILINEAR_INTERPOLATION_BITS == 4 #elif BILINEAR_INTERPOLATION_BITS == 4
#define CHECKSUM 0xD672A457 #define CHECKSUM 0x8B925154
#else #else
#define CHECKSUM 0x00000000 #define CHECKSUM 0x00000000
#endif #endif

View File

@ -8,9 +8,14 @@
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT); uint8_t *alpha;
uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); uint32_t *src, *dest;
uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
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 *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); pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);

View File

@ -307,6 +307,8 @@ main (int argc, char **argv)
{ {
int i, j, a, b, x, y; int i, j, a, b, x, y;
prng_srand (0);
for (i = 0; i < ARRAY_LENGTH (formats); ++i) for (i = 0; i < ARRAY_LENGTH (formats); ++i)
{ {
for (j = 0; j < ARRAY_LENGTH (formats); ++j) for (j = 0; j < ARRAY_LENGTH (formats); ++j)

View File

@ -25,7 +25,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
int max_extra_stride, int max_extra_stride,
pixman_format_code_t *used_fmt) pixman_format_code_t *used_fmt)
{ {
int n = 0, i, width, height, stride; int n = 0, width, height, stride;
pixman_format_code_t fmt; pixman_format_code_t fmt;
uint32_t *buf; uint32_t *buf;
pixman_image_t *img; pixman_image_t *img;
@ -46,15 +46,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
/* do the allocation */ /* do the allocation */
buf = aligned_malloc (64, stride * height); buf = aligned_malloc (64, stride * height);
/* initialize image with random data */ prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
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);
}
img = pixman_image_create_bits (fmt, width, height, buf, stride); img = pixman_image_create_bits (fmt, width, height, buf, stride);
@ -390,6 +382,8 @@ main (int argc, const char *argv[])
{ {
int i; int i;
prng_srand (0);
for (i = 1; i <= 8; i++) for (i = 1; i <= 8; i++)
{ {
initialize_palette (&(rgb_palette[i]), i, TRUE); initialize_palette (&(rgb_palette[i]), i, TRUE);
@ -397,6 +391,6 @@ main (int argc, const char *argv[])
} }
return fuzzer_test_main("blitters", 2000000, return fuzzer_test_main("blitters", 2000000,
0x46136E0A, 0xD8265D5E,
test_composite, argc, argv); test_composite, argc, argv);
} }

View File

@ -251,6 +251,6 @@ test_composite (int testnum,
int int
main (int argc, const char *argv[]) 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); test_composite, argc, argv);
} }

View File

@ -153,14 +153,8 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
} }
else else
{ {
uint8_t *d8;
data = malloc (stride * height); data = malloc (stride * height);
prng_randmemset (data, height * stride, 0);
d8 = (uint8_t *)data;
for (i = 0; i < height * stride; ++i)
d8[i] = prng_rand_n (256);
destroy = destroy_malloced; destroy = destroy_malloced;
} }
@ -333,6 +327,6 @@ int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
return fuzzer_test_main ("glyph", 30000, return fuzzer_test_main ("glyph", 30000,
0x79E74996, 0xFA478A79,
test_glyphs, argc, argv); test_glyphs, argc, argv);
} }

View File

@ -163,7 +163,7 @@ main (int argc, const char *argv[])
{ {
return fuzzer_test_main ("region_contains", return fuzzer_test_main ("region_contains",
1000000, 1000000,
0xD2BF8C73, 0x548E0F3F,
test_region_contains_rectangle, test_region_contains_rectangle,
argc, argv); argc, argv);
} }

View File

@ -32,6 +32,8 @@ main ()
0xffff 0xffff
}; };
prng_srand (0);
/* This used to go into an infinite loop before pixman-region.c /* This used to go into an infinite loop before pixman-region.c
* was fixed to not use explict "short" variables * was fixed to not use explict "short" variables
*/ */

View File

@ -63,10 +63,8 @@ make_image (void)
pixman_format_code_t format = RANDOM_FORMAT(); pixman_format_code_t format = RANDOM_FORMAT();
uint32_t *bytes = malloc (WIDTH * HEIGHT * 4); uint32_t *bytes = malloc (WIDTH * HEIGHT * 4);
pixman_image_t *image; pixman_image_t *image;
int i;
for (i = 0; i < WIDTH * HEIGHT * 4; ++i) prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0);
((uint8_t *)bytes)[i] = prng_rand_n (256);
image = pixman_image_create_bits ( image = pixman_image_create_bits (
format, WIDTH, HEIGHT, bytes, WIDTH * 4); format, WIDTH, HEIGHT, bytes, WIDTH * 4);
@ -108,6 +106,6 @@ int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
return fuzzer_test_main ("rotate", 15000, return fuzzer_test_main ("rotate", 15000,
0x5236FD9F, 0xECF5E426,
test_transform, argc, argv); test_transform, argc, argv);
} }

View File

@ -52,6 +52,7 @@ int
main (void) main (void)
{ {
int i; int i;
prng_srand (0);
for (i = 0; i < 10000; i++) for (i = 0; i < 10000; i++)
{ {
int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1; int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1;

View File

@ -140,14 +140,9 @@ test_composite (int testnum,
maskbuf = (uint32_t *)malloc (mask_stride * mask_height); maskbuf = (uint32_t *)malloc (mask_stride * mask_height);
dstbuf = (uint32_t *)malloc (dst_stride * dst_height); dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
for (i = 0; i < src_stride * src_height; i++) prng_randmemset (srcbuf, src_stride * src_height, 0);
*((uint8_t *)srcbuf + i) = prng_rand_n (256); prng_randmemset (maskbuf, mask_stride * mask_height, 0);
prng_randmemset (dstbuf, dst_stride * dst_height, 0);
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);
src_fmt = get_format (src_bpp); src_fmt = get_format (src_bpp);
dst_fmt = get_format (dst_bpp); dst_fmt = get_format (dst_bpp);
@ -380,11 +375,11 @@ test_composite (int testnum,
} }
#if BILINEAR_INTERPOLATION_BITS == 8 #if BILINEAR_INTERPOLATION_BITS == 8
#define CHECKSUM 0x107B67ED #define CHECKSUM 0x9096E6B6
#elif BILINEAR_INTERPOLATION_BITS == 7 #elif BILINEAR_INTERPOLATION_BITS == 7
#define CHECKSUM 0x30EC0CF0 #define CHECKSUM 0xCE8EC6BA
#elif BILINEAR_INTERPOLATION_BITS == 4 #elif BILINEAR_INTERPOLATION_BITS == 4
#define CHECKSUM 0x87B496BC #define CHECKSUM 0xAB1D39BE
#else #else
#define CHECKSUM 0x00000000 #define CHECKSUM 0x00000000
#endif #endif

View File

@ -27,10 +27,11 @@
#include <png.h> #include <png.h>
#endif #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. * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
@ -423,13 +424,11 @@ uint8_t *
make_random_bytes (int n_bytes) make_random_bytes (int n_bytes)
{ {
uint8_t *bytes = fence_malloc (n_bytes); uint8_t *bytes = fence_malloc (n_bytes);
int i;
if (!bytes) if (!bytes)
return NULL; return NULL;
for (i = 0; i < n_bytes; ++i) prng_randmemset (bytes, n_bytes, 0);
bytes[i] = prng_rand () & 0xff;
return bytes; return bytes;
} }

View File

@ -4,6 +4,7 @@
#include <assert.h> #include <assert.h>
#include "pixman-private.h" /* For 'inline' definition */ #include "pixman-private.h" /* For 'inline' definition */
#include "utils-prng.h"
#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
@ -11,22 +12,32 @@
* taken from POSIX.1-2001 example * 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 #ifdef USE_OPENMP
#pragma omp threadprivate(prng_seed) #pragma omp threadprivate(prng_state_data)
#pragma omp threadprivate(prng_state)
#endif #endif
static inline uint32_t static inline uint32_t
prng_rand (void) prng_rand (void)
{ {
prng_seed = prng_seed * 1103515245 + 12345; return prng_rand_r (prng_state);
return ((uint32_t)(prng_seed / 65536) % 32768);
} }
static inline void static inline void
prng_srand (uint32_t seed) 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 static inline uint32_t
@ -38,22 +49,19 @@ prng_rand_n (int max)
static inline uint32_t static inline uint32_t
prng_rand_N (int max) prng_rand_N (int max)
{ {
uint32_t lo = prng_rand (); return prng_rand () % max;
uint32_t hi = prng_rand () << 15;
return (lo | hi) % max;
} }
static inline uint32_t static inline uint32_t
prng_rand_u32 (void) prng_rand_u32 (void)
{ {
/* This uses the 10/11 most significant bits from the 3 lcg results return prng_rand ();
* (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); 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 /* CRC 32 computation