Uniform random number generators
assembly library

by Agner Fog

randoma.zip contains a library of uniform random number generators of very high quality coded in assembly language for improved speed.

The random number generators found in standard libraries are often of a poor quality, insufficient for large Monte Carlo calculations. This library provides random number generators of a much better quality: Better randomness, higher resolution, and longer cycle lengths. Yet they are still very fast.

The same random number generators are available in the C++ language in the archive randomc.zip.

Non-uniform random number generators are provided in stocc.zip.

System requirements

Microprocessor
This library is coded for Intel-compatible 32-bit microprocessors, such as the Pentium family and similar microprocessors from AMD. This includes the common PC platform. The SSE2 instruction set is used automatically if supported by microprocessor and operating system, but is not required. For hardware platforms using other microprocessors, you have to use the C++ version of the code.
Operating system
Windows 95 and later, DOS, Linux, BSD, UNIX, and similar systems.
Supported programming languages and environments
Several different formats of static and dynamic link libraries are provided to enable linking to the library from different languages such as C, C++, C#, Visual Basic, Pascal, etc., as well as different brands of compilers such as Borland, Microsoft, Intel, Symantec, Gnu, etc.

File list

The archive randoma.zip contains the following files:

randoma.htm
This file. Instructions.
randoma.h
C++ header file containing function prototypes.
You must #include this in all C++ files that use this library.
randomao.lib
Static link library in OMF format.
Use this for Borland and Symantec compilers.
randomam.lib
Static link library in Windows MS-COFF format.
Use this for Microsoft compilers.
randomae.a
Static link library in ELF format.
Use this for Gnu and other compilers under Linux, BSD, UNIX, and similar systems.
randomao.zip
Object files in OMF format.
Contains the same object files as randomao.lib. Use with systems that don't accept lib files, such as Borland Delphi.
randomad.dll
Dynamic link library in Windows format.
Use this with programming languages that cannot use static linking, such as C# and Visual Basic.
random16.zip
For use in 16-bit code, such as DOS and Windows 3.x.
ranlib.cpp
Example showing how to call these library functions from C++
ranlib.cs
Example showing how to call these library functions from C#
ranlib.vb
Example showing how to call these library functions from Visual Basic .net.
ranlib.pas
Function definitions for calling library functions from Borland Delphi Pascal.
ranmoro.cpp
Defines C++ class TRandomMotRot encapsulating library function XRandom() for use as base for C++ class library stocc.
ex-lib.cpp
Example showing how to use these library functions as base for non-uniform random number generators
mersenna.asm
Source code for Mersenne twister random number generator.
mothera.asm
Source code for Mother-of-all random number generator.
ranrot.asm
Source code for RANROT-W random number generator.
motrot.asm
Source code for combined Mother-of-all and RANROT-W random number generator.
detectpr.asm
Used by mersenna.asm to detect support for SSE2 instructions.
randomad.asm, randomad.def
Additional source code for building randomad.dll
randomad.lib
Import library for randomad.dll. It is recommended to use randomam.lib instead.
randomad.txt
Further description of randomad.dll
makefile
Makefile for re-making all library and zip files.

Quality of randomness

All these random number generators provide excellent randomness and extremely long cycle lengths.

For all but the most demanding applications it doesn't matter which of the random number generators you use. The Mersenne twister is the one that is best understood theoretically. For this reason it is recommended by leading experts. The RANROT generators have a more chaotic behavior which is difficult to analyze theoretically, and hence maybe also more random in the sense that it has no mathematical regularity that might interfere with the structure of your application. The Mother-of-all generator has the highest bifurcation of these generators.

For the most demanding scientific applications you may use the combined generator.

These generators are not suited for cryptographic applications because the algorithm is invertible and the complete sequence can be calculated from a limited part of the sequence.

Technical quality

The technical qualities of these generators are compared in the table below. If you want to simulate very low probabilities with high accuracy then it is recommended to use a generator with a high resolution. If speed is important then use a generator that uses a low number of clock cycles. The amount of data cache used influences execution speed if the total amount of data handled by the critical part of your program exceeds the size of the level-1 cache in your microprocessor. A low cache use means faster execution. The same applies to the code cache use if the critical part of your program uses more than the available cache size.

Generator type

coding language resolution
bits

time consumption, clock cycles

data cache use, bytes code cache use, bytes
bits integer float hi.res.
float
RANROT B C++ 32   282 96   164 350
RANROT W C++ 52 or 63 61 306   118 164 400
RANROT W ASM 63 22 67   77 160 200
Mother-of-all C++ 32   306 189   48 220
Mother-of-all ASM 32 74 96 146   48 170
Mersenne Twister C++ 32 38 258 91   1476 450
Mersenne Twister ASM 32 - 63 24 44 65 81 1472 600
Combined
RANROT-W+
Mother-off-all
ASM 63 89 134   130 224 300

The number of clock cycles are approximate values for a Pentium 4 microprocessor under optimal caching conditions. A count of 100 clock cycles means that you can generate 10 million random numbers per second on a 1 GHz computer.

Instructions

This library of random number generators can be included in a C++ project for Windows in 32-bit mode. It can also be linked into projects in other programming languages that allow linking in static or dynamic libraries.

Choose which random number generator you want to use. The different generators are explained above.

All these generators are used in the same way: They must be initialized with a random seed before the first call to any of the random functions. 

The seed can be any integer, positive, negative or zero. Repeating the calculations with the same seed will produce the same sequence of random numbers. A different seed will give different random numbers. You may use the time in seconds or milliseconds as the seed.

Call the appropriate version of _RandomInit with your seed, where  _  is the corresponding prefix letter, before generating any random number. An alternative initialization function TRandomInitByArray is supplied for the Mersenne Twister only. The latter function allows you to use multiple numbers for initializing the random number generator in such a way that the random number sequence generated depends on all bits in all the seed numbers. 

All the generators can generate three different kinds of random numbers:

_IRandom gives a uniformly distributed integer in the interval defined by min and max: min <= x <= max.

_Random gives a uniformly distributed floating point number in the interval 0 <= x < 1. TRandom2 and TRandom3 give extended resolution.

_BRandom gives 32 random bits.

Prefix the function names with one of the following letters instead of _ :
T for the Mersenne twister,
M
for the Mother-of-all generator,
W for the RANROT-W generator, or
X for the combined RANROT-W and Mother-of-all generator.

You need to use only one of these generators.

Write  #include "randoma.h"  in any C++ file that calls these functions. See the file randoma.h for the function prototypes.

You must link one of the library files into your project. Use randomao.lib for Borland and Symantec compilers, randomam.lib for Microsoft and some compilers under Windows, and randomae.a for other operating systems than Windows. These three libraries contain the same object files in different object file formats. If you are in doubt which one to use in your system, then just try. You will get a linker error message if you try the wrong one. Use randomad.dll for programming languages that cannot link with static libraries under Windows, such as C# and Visual Basic.

The files ranlib.cpp, ranlib.cs, ranlib.vb and ranlib.pas contain examples of how to call this library from different programming languages. Try it!

If you want to call this library from other languages than the ones mentioned above then read the documentation for your compiler to see if it is possible to link with external static or dynamic libraries.

Portability

This library has been tested successfully with several different C++ compiler systems under different operating systems. The differences in object file format has been taken care of by providing static link library files in both OMF, MS-COFF and ELF format, and a dynamic link library in Windows format.

The code is not re-entrant (thread safe). If you need to call a random number generator from more than one thread then use the C++ version in randomc.zip and make one instance of the class in each thread with different seeds.

This assembly library cannot be used for 64-bit systems, or for microprocessors that are not compatible with the Intel 80386.

The Mersenne twister code uses SSE2 instructions only on microprocessors and operating systems that support these instructions. It automatically uses an equivalent alternative code when SSE2 is not supported. 

Theory

The theory of the Mersenne twister is given in the article:
M. Matsumoto & T. Nishimura: "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator". ACM Transactions on Modeling and Computer Simulation, vol. 8, no. 1, 1998, pp. 3-30. See also http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html.

The theory of Mother-of-All generators is given in George Marsaglia's DIEHARD package, see stat.fsu.edu/~geo/diehard.html or www.cs.hku.hk/internet/randomCD.html.

The theory of RANROT generators is given at www.agner.org/random/theory/.

General public license

© 1997, 2004 by Agner Fog under GNU General Public License. You may contact me for commercial licenses.

 

Back to random number generators page.