1f4f78bb6Smrg/* 2f4f78bb6Smrg * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com> 3f4f78bb6Smrg * 4f4f78bb6Smrg * Based on the public domain implementation of small noncryptographic PRNG 5f4f78bb6Smrg * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html 6f4f78bb6Smrg * 7f4f78bb6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8f4f78bb6Smrg * copy of this software and associated documentation files (the "Software"), 9f4f78bb6Smrg * to deal in the Software without restriction, including without limitation 10f4f78bb6Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f4f78bb6Smrg * and/or sell copies of the Software, and to permit persons to whom the 12f4f78bb6Smrg * Software is furnished to do so, subject to the following conditions: 13f4f78bb6Smrg * 14f4f78bb6Smrg * The above copyright notice and this permission notice (including the next 15f4f78bb6Smrg * paragraph) shall be included in all copies or substantial portions of the 16f4f78bb6Smrg * Software. 17f4f78bb6Smrg * 18f4f78bb6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19f4f78bb6Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20f4f78bb6Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21f4f78bb6Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22f4f78bb6Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23f4f78bb6Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24f4f78bb6Smrg * DEALINGS IN THE SOFTWARE. 25f4f78bb6Smrg */ 26f4f78bb6Smrg 27f4f78bb6Smrg#include <assert.h> 28f4f78bb6Smrg#include <stdlib.h> 29f4f78bb6Smrg#include "utils-prng.h" 30f4f78bb6Smrg#include "utils.h" 31f4f78bb6Smrg 32f4f78bb6Smrg/* The original code from http://www.burtleburtle.net/bob/rand/smallprng.html */ 33f4f78bb6Smrg 34f4f78bb6Smrgtypedef uint32_t u4; 35f4f78bb6Smrgtypedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx; 36f4f78bb6Smrg 37f4f78bb6Smrg#define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) 38f4f78bb6Smrgu4 ranval( ranctx *x ) { 39f4f78bb6Smrg u4 e = x->a - rot(x->b, 27); 40f4f78bb6Smrg x->a = x->b ^ rot(x->c, 17); 41f4f78bb6Smrg x->b = x->c + x->d; 42f4f78bb6Smrg x->c = x->d + e; 43f4f78bb6Smrg x->d = e + x->a; 44f4f78bb6Smrg return x->d; 45f4f78bb6Smrg} 46f4f78bb6Smrg 47f4f78bb6Smrgvoid raninit( ranctx *x, u4 seed ) { 48f4f78bb6Smrg u4 i; 49f4f78bb6Smrg x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; 50f4f78bb6Smrg for (i=0; i<20; ++i) { 51f4f78bb6Smrg (void)ranval(x); 52f4f78bb6Smrg } 53f4f78bb6Smrg} 54f4f78bb6Smrg 55f4f78bb6Smrg/*****************************************************************************/ 56f4f78bb6Smrg 57f4f78bb6Smrg#define BUFSIZE (8 * 1024 * 1024) 58f4f78bb6Smrg#define N 50 59f4f78bb6Smrg 60f4f78bb6Smrgvoid bench (void) 61f4f78bb6Smrg{ 62f4f78bb6Smrg double t1, t2; 63f4f78bb6Smrg int i; 64f4f78bb6Smrg prng_t prng; 65f4f78bb6Smrg uint8_t *buf = aligned_malloc (16, BUFSIZE + 1); 66f4f78bb6Smrg 67f4f78bb6Smrg prng_srand_r (&prng, 1234); 68f4f78bb6Smrg t1 = gettime(); 69f4f78bb6Smrg for (i = 0; i < N; i++) 70f4f78bb6Smrg prng_randmemset_r (&prng, buf, BUFSIZE, 0); 71f4f78bb6Smrg t2 = gettime(); 72f4f78bb6Smrg printf ("aligned randmemset : %.2f MB/s\n", 73f4f78bb6Smrg (double)BUFSIZE * N / 1000000. / (t2 - t1)); 74f4f78bb6Smrg 75f4f78bb6Smrg t1 = gettime(); 76f4f78bb6Smrg for (i = 0; i < N; i++) 77f4f78bb6Smrg prng_randmemset_r (&prng, buf + 1, BUFSIZE, 0); 78f4f78bb6Smrg t2 = gettime(); 79f4f78bb6Smrg printf ("unaligned randmemset : %.2f MB/s\n", 80f4f78bb6Smrg (double)BUFSIZE * N / 1000000. / (t2 - t1)); 81f4f78bb6Smrg 82f4f78bb6Smrg t1 = gettime(); 83f4f78bb6Smrg for (i = 0; i < N; i++) 84f4f78bb6Smrg { 85f4f78bb6Smrg prng_randmemset_r (&prng, buf, BUFSIZE, RANDMEMSET_MORE_00_AND_FF); 86f4f78bb6Smrg } 87f4f78bb6Smrg t2 = gettime (); 88f4f78bb6Smrg printf ("aligned randmemset (more 00 and FF) : %.2f MB/s\n", 89f4f78bb6Smrg (double)BUFSIZE * N / 1000000. / (t2 - t1)); 90f4f78bb6Smrg 91f4f78bb6Smrg t1 = gettime(); 92f4f78bb6Smrg for (i = 0; i < N; i++) 93f4f78bb6Smrg { 94f4f78bb6Smrg prng_randmemset_r (&prng, buf + 1, BUFSIZE, RANDMEMSET_MORE_00_AND_FF); 95f4f78bb6Smrg } 96f4f78bb6Smrg t2 = gettime (); 97f4f78bb6Smrg printf ("unaligned randmemset (more 00 and FF) : %.2f MB/s\n", 98f4f78bb6Smrg (double)BUFSIZE * N / 1000000. / (t2 - t1)); 99f4f78bb6Smrg 100f4f78bb6Smrg free (buf); 101f4f78bb6Smrg} 102f4f78bb6Smrg 103f4f78bb6Smrg#define SMALLBUFSIZE 100 104f4f78bb6Smrg 105f4f78bb6Smrgint main (int argc, char *argv[]) 106f4f78bb6Smrg{ 107f4f78bb6Smrg const uint32_t ref_crc[RANDMEMSET_MORE_00_AND_FF + 1] = 108f4f78bb6Smrg { 109f4f78bb6Smrg 0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39, 110f4f78bb6Smrg 0xD2321099, 0xFD8C5420, 0xD3B7C42A, 0xFC098093, 111f4f78bb6Smrg 0x85E01DE0, 0x6680F8F7, 0x4D32DD3C, 0xAE52382B, 112f4f78bb6Smrg 0x149E6CB5, 0x8B336987, 0x15DCB2B3, 0x8A71B781 113f4f78bb6Smrg }; 114f4f78bb6Smrg uint32_t crc1, crc2; 115f4f78bb6Smrg uint32_t ref, seed, seed0, seed1, seed2, seed3; 116f4f78bb6Smrg prng_rand_128_data_t buf; 117f4f78bb6Smrg uint8_t *bytebuf = aligned_malloc(16, SMALLBUFSIZE + 1); 118f4f78bb6Smrg ranctx x; 119f4f78bb6Smrg prng_t prng; 120f4f78bb6Smrg prng_randmemset_flags_t flags; 121f4f78bb6Smrg 122f4f78bb6Smrg if (argc > 1 && strcmp(argv[1], "-bench") == 0) 123f4f78bb6Smrg { 124f4f78bb6Smrg bench (); 125f4f78bb6Smrg return 0; 126f4f78bb6Smrg } 127f4f78bb6Smrg 128f4f78bb6Smrg /* basic test */ 129f4f78bb6Smrg raninit (&x, 0); 130f4f78bb6Smrg prng_srand_r (&prng, 0); 131f4f78bb6Smrg assert (ranval (&x) == prng_rand_r (&prng)); 132f4f78bb6Smrg 133f4f78bb6Smrg /* test for simd code */ 134f4f78bb6Smrg seed = 0; 135f4f78bb6Smrg prng_srand_r (&prng, seed); 136f4f78bb6Smrg seed0 = (seed = seed * 1103515245 + 12345); 137f4f78bb6Smrg seed1 = (seed = seed * 1103515245 + 12345); 138f4f78bb6Smrg seed2 = (seed = seed * 1103515245 + 12345); 139f4f78bb6Smrg seed3 = (seed = seed * 1103515245 + 12345); 140f4f78bb6Smrg prng_rand_128_r (&prng, &buf); 141f4f78bb6Smrg 142f4f78bb6Smrg raninit (&x, seed0); 143f4f78bb6Smrg ref = ranval (&x); 144f4f78bb6Smrg assert (ref == buf.w[0]); 145f4f78bb6Smrg 146f4f78bb6Smrg raninit (&x, seed1); 147f4f78bb6Smrg ref = ranval (&x); 148f4f78bb6Smrg assert (ref == buf.w[1]); 149f4f78bb6Smrg 150f4f78bb6Smrg raninit (&x, seed2); 151f4f78bb6Smrg ref = ranval (&x); 152f4f78bb6Smrg assert (ref == buf.w[2]); 153f4f78bb6Smrg 154f4f78bb6Smrg raninit (&x, seed3); 155f4f78bb6Smrg ref = ranval (&x); 156f4f78bb6Smrg assert (ref == buf.w[3]); 157f4f78bb6Smrg 158f4f78bb6Smrg /* test for randmemset */ 159f4f78bb6Smrg for (flags = 0; flags <= RANDMEMSET_MORE_00_AND_FF; flags++) 160f4f78bb6Smrg { 161f4f78bb6Smrg prng_srand_r (&prng, 1234); 162f4f78bb6Smrg prng_randmemset_r (&prng, bytebuf, 16, flags); 163f4f78bb6Smrg prng_randmemset_r (&prng, bytebuf + 16, SMALLBUFSIZE - 17, flags); 164f4f78bb6Smrg crc1 = compute_crc32 (0, bytebuf, SMALLBUFSIZE - 1); 165f4f78bb6Smrg prng_srand_r (&prng, 1234); 166f4f78bb6Smrg prng_randmemset_r (&prng, bytebuf + 1, SMALLBUFSIZE - 1, flags); 167f4f78bb6Smrg crc2 = compute_crc32 (0, bytebuf + 1, SMALLBUFSIZE - 1); 168f4f78bb6Smrg assert (ref_crc[flags] == crc1); 169f4f78bb6Smrg assert (ref_crc[flags] == crc2); 170f4f78bb6Smrg } 171f4f78bb6Smrg 172f4f78bb6Smrg free (bytebuf); 173f4f78bb6Smrg 174f4f78bb6Smrg return 0; 175f4f78bb6Smrg} 176