#!/usr/bin/perl
# -*- mode: cperl; coding: utf-8; -*-
use strict;
use warnings;
use utf8;
use lib "/h/hamren/src/post/lib", "."; my $rval = do "common.pm" || die "$0: common.pm failed ($!) [$@]"; #--- Single-line common initializer
#--- End of header
sub description {
my $arg1 = shift;
p({style=>"padding-left:40pt; text-indent:-30pt;"}, "$arg1", @_);
}
sub file {
my $arg1 = shift;
p({style=>"padding-left:90pt; text-indent:-30pt;"}, "««$arg1»» ", @_);
}
post(
header(),
p("In 1999, George Marsaglia posted a number of random-number generator on several mailing lists. ",
" They are defined as C macros, and use eleven global variables, of which eight are just a single letter.",
" I have made them ito a C++ class containing inline functions.",
" Here is the long but narrow header file:"),
source_file("./marsaglia.h.short.source"),
p("The interesting part is the first five random-number generators."),
table({class => "components-table"},
trow(td("«shr3»" ), td("Three shifts, with a period of 2^32-1.")),
trow(td("«mwc»" ), td("Multiply With Carry, with a period of about 2^60.")),
trow(td("«kiss»" ), td("Keep It Simple Stupid, with a period of about 2^123")),
trow(td("«lfib4»"), td("Lagged Fibonacci, with a period of about 2^287")),
trow(td("«swb»" ), td("Subtract with borrow. Has a very long period: about 2^7578."))),
p("The remaining generators are not recommended for direct use, but are used by the five generators above."),
p("How about execution times?",
" Each generators has been tested by running it 10^9 times.",
" This has been repeatd ten times, and the result sorted.",
" The two sortest and the two longest times have been dropped, and the remaining six values have been averaged."),
p("Each generator has been instantiated in four different ways"),
table({class => "components-table"},
trow(td("«As a static object»"), td("An instance of ««class Marsaglia»» declared as a file-static variable." )),
trow(td("«As an extern object»"), td("An instance of ««class Marsaglia»» defined in another compilation unit.")),
trow(td("«As a stack object»"), td("An instance of ««class Marsaglia»» defined local to a function." )),
trow(td("«As a namespace»"), td("Using a rewrite of ««class Marsaglia»» as a namespace.",
" This, of course, is not an object at all."))),
svg("plot-marsaglia-1,000,000,000.svg"),
p("The generators are ordered by increasing period.",
" The tag «M:» in the plot identifies Marsaglia RNGs. In the next plot, there will be some other RNGs as well"),
p("Time was measured using the C++ library in «std::chrono». ",
" The details are in the "),
p("As can be seen from the table, it really does not matter how the class is instantiated.",
" Variations are withing the margin of error, and another compiler may give different results.",
" The tests were compiled with GCC 9.1.0 with option -O3."),
p("The times in this plot are relative, not absolute.",
" On my Intel box running at 2.4 MHz, the fastest generator takes about 3 nanoseconds per iteration."),
h2("Download"),
p("The source is ",
href("./marsaglia-random-numbers.tar.gz", "available for download"),
". Files include"),
table({class => "components-table"},
trow(td("«Makefile»"), td("Build «marsaglia-expect.elf», and «marsaglia-main.elf»")),
trow(td("«marsaglia.h»"), td("Class definition, including all inline member functions.")),
trow(td("«marsaglia.cc»"), td("The remaining, non-inlined, functions.")),
trow(td("«marsaglia-namespace.h»"), td("The Marsaglia class rewritten as a namespace. For performance testing.")),
trow(td("«marsaglia-main.cc»"), td("Program to verify correctness of «class Marsaglia».")),
trow(td("«marsaglia-expect.c»"), td("Original code, slightly modified to print results instead of zeroes. Output, which is assumed to be correct, is pasted into «marsaglia-main.cc».")),
trow(td("«marsaglia-rng.html»"), td("Marsaglia's 1999 post.")),
trow(td("«rngs/rngs.cc»"), td("Run and time one of the 20+ RNG variation.")),
trow(td("«rngs/rngs.sh»"), td("Run all or some RNG variations")),
trow(td("«rngs/Makefile»"), td("")),
trow(td("«rngs/README»"), td("Do read this.")),
trow(td("«rngs/lib.h»"), td("Utilities for measuring time")),
trow(td("«rngs/lib.cc»"), td("... implementation")),
trow(td("«rngs/mext.cc»"), td("Contains an instance of «class Marsaglia», used by «rngs.cc»."))),
footer()
);
__END__