lemire / testingRNG

Testing common random-number generators (RNG)
Apache License 2.0
172 stars 22 forks source link

Adding PRVHASH PRNG to the test suite. #22

Closed avaneev closed 1 year ago

avaneev commented 3 years ago

Hello, could you add my PRNG which I designed for hashing, to your test suite? The project page is https://github.com/avaneev/prvhash

You'll just need prvhash_core.h file.

The minimal PRNG code follows. I would estimate the minimal period as 2^160. The Seed can be set to any value, each value puts the PRNG at random position.

#include "prvhash_core.h"
#include <stdio.h>

int main()
{
    const uint64_t rc = 1ULL << 27;

    uint64_t Seed = 0;
    uint64_t lcg = 0;
    uint64_t Hash = 0;

    uint64_t v = 0;
    uint64_t i;

    for( i = 0; i < rc; i++ )
    {
        v = prvhash_core64( &Seed, &lcg, &Hash );
    }

    printf( "%llu\n", v );
}
lemire commented 3 years ago

Would you be willing to create a pull request?

avaneev commented 3 years ago

Would you be willing to create a pull request?

Sorry, I'm not very experienced with collaborative features of GitHub. Please simply copy the file to your repository, its license allows this. Also, I do not see any changes coming to this PRNG function anytime soon - looks like it is working well for its goals.

avaneev commented 3 years ago

@lemire There's a new finding about PRVHASH, maybe worth testing as well. "Fused PRNG" arrangement. It shows me 0.41 cycles/byte which is exceptional for a non-SIMD PRNG. It works fine with PractRand. It can be also ported to AVX-512 probably achieveving unbelievable speeds as a result.

#include "prvhash_core.h"
#include <stdio.h>

int main()
{
    uint64_t Seed = 0;
    uint64_t lcg = 0;
    uint64_t Hash = 0;
    uint64_t Seed2 = 0;
    uint64_t lcg2 = 0;
    uint64_t Hash2 = 0;
    uint64_t Seed3 = 0;
    uint64_t lcg3 = 0;
    uint64_t Hash3 = 0;
    uint64_t Hash4 = 0;

    uint64_t v = 0;
    uint64_t v2 = 0;
    uint64_t v3 = 0;

    uint64_t i;

    for( i = 0; i < ( 1ULL << 27 ); i++ )
    {
        v = prvhash_core64( &Seed, &lcg, &Hash );
        v2 = prvhash_core64( &Seed2, &lcg2, &Hash2 );
        v3 = prvhash_core64( &Seed3, &lcg3, &Hash3 );

        uint64_t t = Hash;
        Hash = Hash2;
        Hash2 = Hash3;
        Hash3 = Hash4;
        Hash4 = t;
    }

    printf( "%llu %llu %llu\n", v, v2, v3 );
}