2013-06-14 11 views
5

skonfigurować następujące minimalne przykład:MATLAB: Jak ustawić losowe ziarno w parfor, aby uzyskać takie same wyniki, jak w przypadku serii?

rng(0); 

randseedoffset = random('unid', 10^5) + 1; 

t = cell(10,1); 
for i = 1:10 
    rng(randseedoffset+i); 
    t{i} = random('unid', 1000); 
end 

disp(t); 

To będzie generować 10 liczb losowych i przechowywać je w t. Zawsze będzie generował te same losowe liczby w niezawodny sposób, ponieważ ustawiam ziarno na rng w pętli for.

Jeśli teraz zmienię for na parfor, otrzymam różnych wyników! Chociaż zawsze będą odtwarzalne.

Chcę przyspieszyć mój kod z parfor i nadal uzyskać takie same dokładnie takie same jak w przypadku liczb losowych dla ...

Odpowiedz

6

Ok, ja po prostu znaleźć przyczynę:

MATLAB obsługuje różne liczb losowych algorytmów genereation . W zwykłym ustawieniu aktualnej wersji jest to Mersenne Twister. Po przejściu do pętli parfor zmienia się to w coś, co nazywa się "Połączoną metodą rekursywną".

Problemem może być ustalona przez jawnie ustawić typ do 'twister' w pętli:

parfor i = 1:10 
    rng(randseedoffset+i, 'twister'); 
    t{i} = random('unid', 1000); 
end 
+0

Interesujące. Nie mogę znaleźć zmiany domyślnego generatora wymienionego gdziekolwiek w dokumentacji. Czy wiesz, czy wpływa to również na 'rand' i' randn'? Przy okazji, możesz zaakceptować własną odpowiedź na swoje pytanie. – horchler

+0

+1 Bardzo interesujące. Bądź ostrożny z tym hackerem w większych kontekstach kodu - wygląda na to, że równolegli robotnicy mają teraz ustawione prawie równoległe stany RNG, a przyszłe 'parfor' lub inne wywołania DCT, które nie ustawiają ponownie nasion mogą mieć dziwne wyniki. Wstępne generowanie liczb losowych poza pętlą może być czystsze, jeśli potrzebujesz całkowitej powtarzalności. –

+0

Mam przeciwną sytuację. Czy mógłbyś odpowiedzieć na moje pytanie: http: //stackoverflow.com/questions/40190243/matlab-generating-random-numbers-in-parfor-or-parallel-computing? Noredirect = 1 # comment67680730_40190243 – kyle

0

czuję potrzebę opracowania na ten temat. Nie resetuj nasion w pętli parfor, a ponadto nie używaj równolegle algorytmu Twister Mersenne (otrzymasz słabe wyniki statystycznej niezależności).

Powodem uzyskania różnych wyników jest to, że algorytm jest inny z powodu właściwości statystycznych, które te liczby powinny utrzymać. W równoległej puli MATLAB ustawi algorytm na 'combRecursive' i ustawi inny podstrum na każdym z robotów, więc dla liczb losowych jesteś dobry. Ponadto, pętla parfor nie gwarantuje —

  • Kolejność, w jakiej pętle postępować,
  • których pracownicy będą wykonujący każdy kawałek lub
  • ilu iteracji wykonywane są na każdego pracownika.

Dlatego generowanie liczb losowych w pętlach parfor nie zwróci zwykle tych samych liczb losowych, nawet w tym samym stanie na każdym z nich. Zamiast zrobić RandStream ze strumieni algorytmu combRecursive ustawić globalny strumień na każdego pracownika w sPmd bloku, a następnie generować numery na każdego pracownika w sPmd bloku:

p = gcp; % Get or open a pool 

numWork = p.NumWorkers; % Get the number of workers 

s = RandStream.create('mrg32k3a','NumStreams',numWork,... 
    'CellOutput',true); % create numWork independent streams 

n = 200; % number of values to generate on each worker 
spmd 
    RandStream.setGlobalStream(s{labindex}); 
    x = rand(1,n); 
end 

% I generate row vectors as the Composite matrix x will return a 
% comma-separated list using the syntax, x{:}, which can then be 
% concatenated into a single vector: 
randVals2 = [x{:}]'; 
+0

bardzo interesujące. Wydaje się, że parfor sprawia, że ​​sprawy stają się nieporządane, gdy przechodzę z pętli na parfor: czy mógłbyś odpowiedzieć na moje pytanie: http://stackoverflow.com/questions/40190243/matlab-generating-random-numbers-in-parfor-or-parallel- computing? noredirect = 1 # comment67680730_40190243 – kyle

0

spróbować tego:

p = gcp; % Get or open a pool 

numWork = p.NumWorkers; % Get the number of workers 

stream = RandStream('mrg32k3a','seed',mydata.seed); 
RandStream.setGlobalStream(stream); 

% s = RandStream.create('mrg32k3a','NumStreams',numWork,'CellOutput',true,'Seed',mydata.seed); % create numWork independent streams 

n = 200; % number of values to generate on each worker 
spmd 
RandStream.setGlobalStream(stream); 
x = rand(1,n); 
end 
Powiązane problemy