Need a Fast Random Generator for C++

What is a good random number generator for a game?

George Marsaglia has developed some of the best and fastest RNGs currently available
Multiply-with-carry being a notable one for a uniform distribution.

=== Update 2018-09-12 ===

For my own work I'm now using Xoshiro256**, which is a sort of evolution/update on Marsaglia's XorShift.

=== Update 2021-02-23 ===

In .NET 6 (currently in preview) the implementation of System.Random has been changed to use xoshiro256**, but only for the parameterless constructor. The constructor that takes a seed uses the old PRNG in order to maintain backwards compatibility. For more info see Improve Random (performance, APIs, ...)

Faster than rand()?

static unsigned int g_seed;

// Used to seed the generator.
inline void fast_srand(int seed) {
g_seed = seed;
}

// Compute a pseudorandom integer.
// Output value in range [0, 32767]
inline int fast_rand(void) {
g_seed = (214013*g_seed+2531011);
return (g_seed>>16)&0x7FFF;
}

How to generate a random int in C?

Note: Don't use rand() for security. If you need a cryptographically secure number, see this answer instead.

#include <time.h>
#include <stdlib.h>

srand(time(NULL)); // Initialization, should only be called once.
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.

On Linux, you might prefer to use random and srandom.

Fast Random Generator

The fact that you're filling bytes with integers is different enough from the typical usage case for System.Random that you can probably beat it badly if you really need to.

System.Random is made for general use. (In fact, I usually find system random routines uninspiring when I do speed and distribution tests on them.) There are cases where you'd want something else. But you have to be very explicit about your needs. How fast? What are you willing to give up?

If you really need "fast," Marsaglia has produced a number of very fast random number generators that could be adapted to your needs. Here are a few links about one of them, Xorshift:

  • Xorshift (Wikipedia)
  • Fastest implementation of Xorshift in C#, and measurements comparing it to System.Random
  • The Diehard tests are interesting.
  • Agner has C++ code for many fast randoms.
  • Here's a fast twister that uses SIMD instructions.

The last one addresses the fact that you are targeting bytes.

I've only needed super fast randoms a few times. In console games with slow processors where random could make the difference between hitting the frame rate target and not hitting it. What is your use case? By all means, use System.Random if you can.

Or, adapt the routine you link to in your question (which the author claims is 8x the speed of System.Random.)

Fast pseudo random number generator for procedural content

Seems like you're asking for a hash-function rather than a PRNG. Googling 'fast hash function' yields several promising-looking results.

For example:

uint32_t hash( uint32_t a)
a = (a ^ 61) ^ (a >> 16);
a = a + (a << 3);
a = a ^ (a >> 4);
a = a * 0x27d4eb2d;
a = a ^ (a >> 15);
return a;
}

Edit: Yep, some hash functions definitely look more suitable than others.

For your purposes, it should be sufficient to eyeball thefunction and check that a single-bit change in the input will propagate to lots of output bits.

What is the best way to generate random numbers in C++?

If and only if:

  • you are not looking for "perfect uniformity" or

  • you have no C++11 support and not even TR1 (thus you don't have another choice)

then you might consider using the following C-style solution, which (for the sake of the reputation of this community ~ see rand() Considered Harmful) is written in strike-through font:

Here's the simple C-style function that generates random number from the interval from min to max, inclusive. Those numbers seem to be very close to being uniformly distributed.

int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}

and don't forget to call srand before you use it:

int occurrences[8] = {0};

srand(time(0));
for (int i = 0; i < 100000; ++i)
++occurrences[irand(1,7)];

for (int i = 1; i <= 7; ++i)
printf("%d ", occurrences[i]);

output: 14253 14481 14210 14029 14289 14503 14235

Also have a look at:

Generate a random number within range?

Generate random numbers uniformly over an entire range

and find some time and watch at least first 11 minutes of aforementioned video

Otherwise:

use <random> just like it was pointed out by Kerrek SB already.

Fast C random boolean generator

Extracting say the last bit of a random number can wreak havoc as linear congruential generators can alternate between odd and even numbers1. A scheme like clock() & 1 would also have ghastly correlation plains.


Consider a solution based on the quick and dirty generator of Donald Kunth: for uint32_t I, sequence

I = 1664525 * I + 1013904223;

and 2 * I < I is the conditional yielding the Boolean drawing. Here I'm relying on the wrap-around behaviour of I which should occur half the time, and a potentially expensive division is avoided.

Testing I <= 0x7FFFFFFF is less flashy and might be faster still, but the hardcoding of the midpoint is not entirely satisfactory.


1 The generator I present here does.



Related Topics



Leave a reply



Submit