Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Change LCG in garbage collector treap to use full 64 bits of state instead of 48 #3042

Merged
merged 1 commit into from
May 20, 2020

Conversation

n8sh
Copy link
Member

@n8sh n8sh commented Apr 19, 2020

rt.util.random.Rand48 is an LCG that holds its state in a 64-bit long but only makes use of the low 48 bits. Replacing it with an LCG that makes use of the full 64 bits is a strict improvement as it takes no additional space and is not slower.

This PR renames Rand48 to "Rand" so the name will not be misleading. "Rand64" was not chosen because it could give the misimpression that the output is 64 bits.

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @n8sh!

Bugzilla references

Auto-close Bugzilla Severity Description
20746 enhancement Change LCG in garbage collector treap to use full 64 bits of state instead of 48

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + druntime#3042"

@dlang-bot dlang-bot added the Enhancement New functionality label Apr 19, 2020
Copy link
Contributor

@MoonlightSentinel MoonlightSentinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have proof that this improves the LCGs output? The current configuration matches C's drand48 and truncations is a common technique to improve the output of an LCG.

@n8sh
Copy link
Member Author

n8sh commented Apr 25, 2020

truncations is a common technique to improve the output of an LCG.

The replacement also uses truncation. Its exposed output is the top 32 bits of a 64 bit state; lrand48 exposes as output the top 32 bits of a 48 bit state.

Do you have proof that this improves the LCGs output?

I can prove it has a greater period ;), and every possible two-uint sequence appears in its output with equal frequency (that is, it is two-dimensionally equidistributed) unlike lrand48 which will never output certain two-uint sequences.

@MoonlightSentinel
Copy link
Contributor

MoonlightSentinel commented Apr 26, 2020

I can prove it has a greater period ;), and every possible two-uint sequence appears in its output with equal frequency (that is, it is two-dimensionally equidistributed) unlike lrand48 which will never output certain two-uint sequences.

That sounds promising, do you have references for those values (esp. c = 1)? E.g. this source suggests c = 3037000493.

@n8sh
Copy link
Member Author

n8sh commented Apr 26, 2020

The multiplier 2862933555777941757 comes from Tables of Linear Congruential Generators of Different Sizes and Good Lattice Structure (L'Ecuyer, 1999). As for the choice of c, I have no proof that any odd number is better than any other odd number, so I picked one with a small representation so on a wide variety of processors it can be used as an immediate value instead of loaded from a constant pool.

@dlang-bot dlang-bot merged commit 0068295 into dlang:master May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Enhancement New functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants