#!/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__