I first noticed something 'strange' about PowerBASIC's RND in January 2016. If I used RND in a primary thread and a secondary thread the throughput collapsed. One of the members, Paul Dixon, is an expert on threads, and he wrote: "When both threads call the same code to generate the next number there's a conflict with 2 CPU cores trying to change the same memory locations and the CPU has to re-cache the new number across all the CPU cores before it can continue. In effect, you're repeatedly forcing a cache miss which slows everything down." Sharing the RND code is not an issue but RND uses memory to remember its state vector and that is used on the next call to RND. With RND used in two separate threads the same memory, holding the state vector, is being changed by the two threads and that is where the conflict is.
In the thread 'So, RND is not thread safe then.' Mersenne Twister (MT) comes in at 84MHz. However, if MT is used in a primary thread and a secondary thread the throughput for each drop to 42MHz. MT's state vector is also being changed by the two threads. When I looked at PCG32 I duplicated everything in sight and got no collisions. I wrote that thread in June 2017 only a few months as a member of the forum. St_W introduced me to using procedures in UDTs leading me to PCG32II and I thought it was that when no collisions occurred.
In fact, the reason no collisions occurred was because the state vector was being duplicated and not because the generator was in the UDT. Each time the UDT is used a new memory location is created for the state vector so it will only be changed by the new UDT instance and, therefore, no conflict.
It still makes sense to have the generator as an element of the UDT otherwise we would have to duplicate it but that has nothing to do with collisions.
I no longer disagree with fxm and stand corrected with everything he wrote.
All of FreeBASIC's generators can be made thread safe if each instance can be given a unique memory location for its state vector. That should not be difficult if all the state vectors were the same size, but they are not. However, that should not be unsurmountable. Can I do it? Maybe, but I can think of a few who would get there a lot quicker than me.
Thread local storage? I am not acquainted with that but is sounds interesting.
So, who needs a thread safe RND anyway? Not many but coderJeff is looking at it and, I cannot remember which, but two languages at least have thread safe generators, and they did not develop them for the fun of it.
Added:
I then wrote: "It would seem that is also false. It looks like we are using the same sequence but different entry points."Yours truly wrote:So, if pcg32A and pcg32B are seeded differently then not only are we using two separate sequences we are using different sequences.
Oh dear, that is wrong. PCG32 uses a seed and a sequence number. If pcg32A and pcg32B use a different sequence number then we are using different sequences. The state vector is seed and sequence. If we use the same sequence number but a different seed then we are using the same sequence but different entry points. It is amazing what we forget as time marches on.
Corection: In the last paragraph I wrote "The state vector is seed and sequence." That should read "The state vector is state and sequence." The initial state is the seed and it gets updated on each random number request. Even that is not strictly true because the generator is warmed up by burning a bunch of outputs before releasing any random numbers to us.