[Bench!][Mir] +54%..+185% performance boost for Mersenne Twister.
Ilya Yaroshenko via Digitalmars-d
digitalmars-d at puremagic.com
Tue Dec 13 15:18:26 PST 2016
On Tuesday, 13 December 2016 at 18:15:25 UTC, Joseph Rushton
Wakeling wrote:
> On Saturday, 26 November 2016 at 20:13:36 UTC, Andrei
> Alexandrescu wrote:
>> Congrats! Also thanks for using the Boost license which would
>> allow backporting the improvements to Phobos. Who'd be up for
>> it?
>
> I've finally found a moment to look into this (I'm at home
> recovering from a seasonal virus, which ironically puts some
> time and mental space in my hands).
>
> It makes for an interesting comparison. The traditional
> Mersenne Twister algorithm generates N random words in one go,
> and then iterates over them, before generating another N random
> words, and so on. (Word == unsigned integer type.)
>
> By contrast Ilya's implementation just updates the single next
> entry in the static array that stores the state of the engine.
> This would seem to work out cheaper on average: perhaps because
> the update-a-variate code stays hotter, perhaps because it
> involves less branching and looping. It certainly makes for a
> simpler, easier to follow update.
>
> However, it might be a good idea to benchmark this in a context
> where there are a lot of random variates being generated, but
> where other things are also happening that might render the
> update code less "hot" than a straightforward `foreach` loop
> benchmark. (Maybe try it out with a Monte Carlo simulation
> ...?)
> The tradeoff between many cheap updates and one expensive one,
> versus all updates being a little more expensive but less on
> average, might not be viable in some practical use-cases.
>
> The Phobos implementation also includes a check on whether the
> generator is properly seeded, which is performed in every
> `popFront()`, which has a reasonably significant impact.
> Ilya's implementation can get away with not performing that
> check because it uses `@disable this();` to remove the
> possibility of initializing the generator without it being
> properly seeded. The impact of that check can possibly be
> lessened by making it a boolean comparison rather than the
> existing `size_t` equality comparison.
>
> -- action item here: could we deprecate `this()` in Phobos as
> a precursor to removing
> the opportunity to instantiate a generator without
> properly initializing it?
>
> I'm going to try to put together a range-based version to see
> if this also makes any difference. I'll post some benchmarks
> of my own once that's done, and if all looks good I'll try to
> put a Phobos PR together.
>
> A few questions -- not blockers, but nice to understand:
>
> * @Ilya, is this implementation your own design, or do you
> have a reference
> for the rationale behind this revised implementation of MT?
My own.
> * Is there a particular reason why the `index` variable is a
> `Uint` (i.e.
> the word type of the generator) rather than a `size_t`? I
> presume there's
> a motivation, since the casting back and forth in `opCall`
> would otherwise
> seem inconvenient.
If I remember correctly it is used with Using, so I use the same
type.
> * Is there a motivation for the reverse iteration through the
> RNG state array?
Yes, it composes add/sub with cmp operations.
Ilya
More information about the Digitalmars-d
mailing list