Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify status of RNG being thread-safe #46280

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

alecloudenback
Copy link
Contributor

I found the documentation about the thread-safe nature of the default RNG to be confusing. I understand now that the thread-safe nature is due to the construction of the DEFAULT_RNG and not a characteristic of, e.g. Xoshiro.

See this short discussion on Zulip for more where this change in documentation was proposed: https://julialang.zulipchat.com/#narrow/stream/274208-helpdesk-.28published.29/topic/Threaded.20.60randn.60.20and.20benchmarking.20error/near/291960004

@ViralBShah ViralBShah added the randomness Random number generation and the Random stdlib label Aug 10, 2022
In a multi-threaded program, you should generally use different RNG objects from different threads
or tasks in order to be thread-safe. However, the default RNG is thread-safe as of Julia 1.3
(using a per-thread RNG up to version 1.6, and per-task thereafter).
In a multi-threaded program, you should generally use different RNG objects from different threads or tasks in order to be thread-safe and deterministic (if given a specific seed). However, the default global RNG is thread-safe as of Julia 1.3 (using a per-thread RNG up to version 1.6, and per-task thereafter). The global RNG refers to per-thread RNG instances; If you instantiate a non-global RNG, you should create a new RNG instance for each thread to avoid possible data-races.
Copy link
Member

Choose a reason for hiding this comment

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

The

The global RNG refers to per-thread RNG instances; If you instantiate a non-global RNG, you should create a new RNG instance for each thread to avoid possible data-races.

seems like it is just saying the same thing as the earlier stuff in the paragraph again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here was my confusion so maybe there's a clearer way to get this across. Per the prior docs:

  1. The global RNG is thread safe
  2. Xoshiro is used as the global RNG
  3. Therefore, if I use a newly instantiated Xoshiro (call it X), I can have code in multiple threads reference X without issues.

#3 is not correct because the Global RNG is constructed in a way that makes it thread safe and that's the point that I don't think comes across previously and what

The global RNG refers to per-thread RNG instances; If you instantiate a non-global RNG, you should create a new RNG instance for each thread to avoid possible data-races.

Is trying to differentiate from what was stated before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to clarify in the latest commit

Comment on lines +21 to +22

The default global RNG is thread-safe as of Julia 1.3 (using a per-thread RNG up to version 1.6, and per-task thereafter). The global RNG refers to per-thread RNG instances; If you instantiate a non-global RNG, you should create a new RNG instance for each thread to avoid possible data-races. That is, even if using the `Xoshiro`, the manually created RNG must be done per thread (the global RNG is thread-safe not via `Xoshiro itself, but by the details of the global RNG handling).
Copy link
Member

Choose a reason for hiding this comment

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

I find this new wording too confusing.

The first point is that we do not talk about the "global RNG", at this point in the page we didn't define it. Nowadays we should only talk about the "default RNG" in the manual, which is the RNG used by default when no explicit RNG is passed.

Otherwise, it looks like all the information was already there. If you want to insist on your point, I would just add to the already existing paragraph something along the lines of:

do note that while Xoshiro and the default RNG both implement the same RNG algorithm, the default RNG is thread-safe but Xoshiro is not.

@StefanKarpinski
Copy link
Member

Here's what I wrote on Zulip about this:

The PR strikes me as making matters more rather than less confusing. It may be possible to improve the docs though.

RNG objects are not individually threadsafe: if you try to use the same RNG from multiple tasks concurrently, it will cause races. “The global RNG” is threadsafe because there is no single global RNG, there are per-task RNGs that can be safely used concurrently because each task has its own, and this per-task RNG is what’s used when you don’t provide an explicit RNG.

Maybe something from that comment can be used to clarify the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
randomness Random number generation and the Random stdlib
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants