delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/02/17/13:50:44

From: George Marsaglia <geo AT stat DOT fsu DOT edu>
Newsgroups: comp.lang.c,comp.os.msdos.djgpp
Subject: An inline assembler RNG for C
Date: Wed, 17 Feb 1999 13:35:29 -0500
Organization: Florida State University
Lines: 108
Message-ID: <36CB0BF1.23FF9E2@stat.fsu.edu>
NNTP-Posting-Host: dial209.acns.fsu.edu
Mime-Version: 1.0
X-Mailer: Mozilla 4.08 [en] (Win95; I)
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

After a number of requests for random number generators
in C, I thought it worthwhile to learn enough C to suggest
a few methods.   A posting of the methods in sci.stat.math,
sci.math and sci.math.num-analysis led to a number of responses
and improvements.  The various postings may be found in those newsgroups

or via deja news (a search on LFIB4 may be the most effective).

But one of my most promising methods cannot be implemented
directly in C, and the main purpose of this posting is to
seek help on how it might be done, via inline assembler.

The method is Multiply-with-Carry for 32-bit integers.
This is the idea.  Suppose you have
          a current 32-bit integer x
          a current 32-bit carry   c
          a fixed multiplier, say, a=2083801278
Now form  a*x+c in 64 bits.
Return the bottom 32 bits as the new x,
and keep the top 32 bits as the new carry, c.

The sequence of x's produced by repeating this process
has many desirable properties.  A listing of some of them
is deferred to the end of this posting, in order to
get directly to my appeal for help in C.

The problem is to form a*x+c in 64 bits, then extract the
bottom and top halves. This is easily done in assembler.
For Intel chips, these instructions do the job:
           mov      eax,x
           mov      edx,2083801278
           mul      edx           ; a*x in edx:eax
           mov      ecx,c         ; get carry
           add      eax,ecx       ; right half of a*x+c in eax
           adc      edx,0         ; if overflow, increment edx
           mov      c,edx         ; store new carry
           mov      x,eax         ; store new x
           ret

According to various posts to this group, many C compilers
seem to permit inline assembler calls, but details vary.

If you are familiar with how inline assembler works
for C compilers you use, and can provide a version of
the above for those compilers, a posting might be of
interest to many potential users.

George Marsaglia


Advantages of the 32-bit multiply-with-carry RNG:

It exploits the built-in arithmetic modulo 2^32
that almost all modern CPU's provide.

It is very fast.

It uses multiplication, which experience has shown
does a better job of mixing bits than do other
RNG methods based on +,- or xor.

It has period "billions and billions" of times longer
than those of ordinary congruential generators.

It produces the trailing 32-bits of a congruential
generator modulo a very large prime.
If integers z(n)=a*z(n-1) mod a*2^32-1 are formed,
the sequence z(n) mod 2^32 is the sequence of x's
produced by the 32-bit multiply-with-carry method.

The trailing bits of the x's do not have the regularity
that is present in standard congruential generators
for modulus 2^32.   Indeed, if only the last bits
of successive x's are used to form a large binary file,
that file will pass all the tests in the Diehard Battery of
tests of randomness.  (http://stat.fsu.edu/pub/diehard/cdrom),
as do the full set of 32-bit integers from MWC.
The theory behind MWC is in the file mwc1.ps of the CDROM.

Any choice of multiplier 'a' from this list:
1791398085 1929682203 1683268614 1965537969 1675393560
1967773755 1517746329 1447497129 1655692410 1606218150
2051013963 1075433238 1557985959 1781943330 1893513180
1631296680 2131995753 2083801278 1873196400 1554115554
can serve as multiplier, or any 'a' for which both
 a*2^32-1 and a*2^31-1 are prime.

The method seems ideally suited for modern CPU's.
I have predicted that it will be the system
generator in  future platforms.  Because it is so
well suited for implementation directly in the
CPU, it has been adopted by several manufacturers
in the gaming industry.  If you play a slot
machine in Las Vegas, chances are  your luck---
good or bad---will be determined by the x's in a
32-bit MWC sequence. The second manufacturer to
use the method was sued by the first, on the
grounds that they were the first to provide a
hardware implementation.   Since a mathematical
algorithm cannot be patented, I don't profit from
its use.

But I, and perhaps many followers of this group,  might
profit intellectually,  should any experts provide  inline assembler
versions for C compilers we use.

gm

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019