3 ms·
I don’t see why it requires locking. You could easily have a TLS seed that gets initialized from the main thread RNG that’s seeded with Rand.seed. No locking re
by vlovich123 2y ago
I don’t see why it requires locking. You could easily have a TLS seed that gets initialized from the main thread RNG that’s seeded with Rand.seed. No locking required. It’s not like reading from a single RNG state from multiple thread with locks is any extra deterministic over that approach since you fundamentally would have to synchronize at a higher level to guarantee that the RNG is read deterministically across all thread orderings.
- yuliyp 2y agoI think the point is that the library probably should assume that if you called `Rand.seed` and/or `srand` it's because you intended to get a specific sequence of random numbers out of it.
- vlovich123 2y agoWhat did I write that suggests you wouldn’t get a deterministic specific sequence equivalent to a lock within the RNG? What I said is if you fail to synchronize the surrounding code’s order of calls into the RNG, then you’re going to have non-determinism anyway even with locks within the RNG. For example: T1: If rng() < 0.5 { Rng() } T2: Rng() The specific numbers returned by calls to rng() depend on the thread ordering UNLESS the user carefully has higher level synchronization themselves to guarantee the ordering. This shows that the locking within the RNG is insufficient and the better performing option that maintains equivalent invariants should be selected (i.e. initialize the TLS RNG state for the new thread from a call to read entropy from the current thread’s RNG state).
- yuliyp 2y agoI'm trying to figure out how you switch "into" thread-local prng mode after a call to srand. Case 1: T1: srand(); rng(); rng() T2: no calls to rng Case 2: T1: srand(); T2: (spawns after the srand call) rng(); rng() How would T2 know that it should produce the seeded sequence as opposed to one based on its own prng?
- vlovich123 2y agosrand sets a TLS flag and the thread spawning code checks that flag on-thread to know how to initialize the off-thread rng).
- owl57 2y agoIn Go or any other runtime that schedules code implicitly on multiple OS threads, this wouldn't work: application writer can (and should, if they need deterministic results) ensure that reads from RNG are done in some specific order, but which of these reads will run on which thread is still non-deterministic, and so will be the results if the library uses thread-local RNG state.
- vlovich123 2y agosure, a work stealing runtime presents a problem where you wouldn’t use TLS but instead use whatever TLS equivalent is appropriate as TLS+work stealing is a bad idea generally anyway. You want to use fiber-local storage eg dispatch_queue_set_specific for libdispatch, whatever mechanism is available for goroutine-local like Context or sync.Map according to ChatGPT). Btw, if you don’t use goroutines then this problem doesn’t come up I believe as that’s the only situation this comes up in. And since Rand is part of the stdlib, I’m sure they could leverage lower level hooks to accomplish fiber-local storage in an efficient manner.