Bill Allombert on Sat, 13 May 2023 16:36:15 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Question about random() and threads...


On Sat, May 13, 2023 at 08:37:48AM -0500, wraithx@morpheus.net wrote:
> Hello,
> 
> I was wondering how the random() function was implemented?  I see in the
> documentation it mentions "a single internal generator", but if I use
> threads, with parfor() or similar, then I was wondering:
> 
> 1) Is there a unique internal generator per thread?  ie Each thread can have
> it's own starting seed and produce it's own sequence of random values?

Yes. Each thread has a separate generator that starts in the same state (setrand(1))

For example if you have 8 threads:

parisizemax = 4000002048, primelimit = 500000, nbthreads = 8
? parvector(8,i,random())
%1 = [1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796]
? parvector(8,i,random())
%2 = [1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796]
? parvector(8,i,random())
%3 = [1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796]
? parvector(8,i,random())
%4 = [1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796,1546275796]

(here each threads is used exactly one)

If you have only 4 threads:
? default(nbthreads,4)
? parvector(8,i,random())
%6 = [1546275796,1546275796,1546275796,1546275796,879788114,879788114,879788114,1745191708]
? parvector(8,i,random())
%7 = [1546275796,1546275796,1546275796,1546275796,879788114,879788114,879788114,879788114]
? parvector(8,i,random())
%8 = [1546275796,1546275796,1546275796,1546275796,879788114,879788114,879788114,1745191708]
? parvector(8,i,random())
%9 = [1546275796,1546275796,1546275796,1546275796,879788114,879788114,879788114,1745191708]

(some threads are reused, so the random state is reused).

As rule, nothing is shared between threads, because we also support MPI (where threads do not share
memory).

To avoid this, you can use setrand to provides different starting state to each threads:

? my(V=vector(8,i,random()));parvector(8,i,setrand(V[i]);random())
%13 = [1834362136,1880444699,481818904,410565656,466627378,2013381622,67736138,1882161884]

Cheers,
Bill.