Генерация случайных чисел внутри spmd в matlab
Я выполняю симуляцию Монте-Карло в Matlab с использованием распараллеливания из-за большого времени, которое требуется для запуска симуляции.
Основная цель - создать действительно большой набор данных панели и использовать его для оценки некоторых регрессий.
Проблема в том, что когда я запускаю симуляцию без параллелизма, они запускают ОЧЕНЬ много времени, поэтому я решил использовать опцию spmd. Однако результаты выполнения распараллеленного кода сильно отличаются от нормального.
rng(3857);
for r=1:MCREP
Ycom=[];
Xcom=[];
YLcom=[];
spmd
for it=labindex:numlabs:NT
(code to generate different components, alpha, delta, x_it, eps_it)
%e.g. x_it=2+1*randn(TT,1);
(uses random number generator: rndn)
% Create different time periods observations for each individual
for t=2:TT
yi(t)=xi*alpha+mu*delta+rho*yi(t-1)+beta*x_it(t)+eps_it(t);
yLi(t)=yi(t-1);
end
% Concatenate each individual in a big matrix: create panel
Ycom=[Ycom yi];
Xcom=[Xcom x_it];
YLcom=[YLcom yLi];
end
end
% Retrieve data stored in composite form
mm=matlabpool('size');
for i=1:mm
Y(:,(i-1)*(NT/mm)+1:i*(NT/mm))=Ycom{i};
X(:,(i-1)*(NT/mm)+1:i*(NT/mm))=Xcom{i};
YL(:,(i-1)*(NT/mm)+1:i*(NT/mm))=YLcom{i};
end
(rest of the code, run regressions)
end
Интенсивная часть кода - та, которая распараллелена с spmd, она создает действительно большой набор данных панели, в котором столбцы являются независимыми индивидуумами, а строки - зависимыми периодами времени.
Моя главная проблема заключается в том, что когда я запускаю код, используя параллель, результаты отличаются от тех, которые я не использую, более того, результаты отличаются, если я использую 8 или 16 работников. Однако с течением времени невозможно выполнить код без распараллеливания.
Я считаю, что проблема исходит от генерации случайных чисел, но я не могу исправить начальное число внутри spmd, потому что это означает исправление начального числа внутри цикла Монте-Карло, поэтому все повторы будут иметь одинаковые числа.
Я хотел бы знать, как я могу починить генератор случайных чисел таким образом, чтобы не важно, сколько рабочих я использую, он даст мне те же результаты.
PS. Другим решением было бы сделать spmd в самом внешнем цикле (цикл Монте-Карло), однако я не вижу увеличения производительности, когда я использую распараллеливание таким образом.
Большое спасибо за Вашу помощь.
1 ответ
Хех... случайные генераторы в параллельном выполнении MATLAB - это действительно проблема.
На веб-странице MATLAB о случайных генераторах ( http://www.mathworks.com/help/matlab/math/creating-and-controlling-a-random-number-stream.html) говорится, что только два потока / генератора могут иметь несколько потоки. Эти два имеют ограниченный период (см. Таблицу по предыдущей ссылке).
НО!!! Генератор по умолчанию (mt19937ar
) можно посеять, чтобы получить разные результаты:)
Таким образом, вы можете начать с mrg32k3a
, получить случайное число в каждом работнике, а затем использовать это случайное число вместе с индексом работника для заполнения mt19937ar
генератор.
Например
spmd
r1 = rand(randStream{labindex}, [1 1]);
r2 = rand(randStream{labindex}, [1 1]);
rng(labindex+(r1/r2), 'twister');
% Do you stuff
end
Конечно, r1
а также r2
можно изменить (или, может быть, добавить больше r
s) для более сложного посева.