我正在使用并行化在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个worker或16个worker,结果会有所不同。但是,在没有并行化的情况下运行代码是不可行的。
我认为问题来自随机数生成,但我无法修复spmd中的种子,因为这意味着将种子固定在蒙特卡洛循环中,因此所有重复都将具有相同的数字。
我想知道如何修复随机数生成器,使得我使用它的工人数量无关紧要。
PS。另一个解决方案是在最外层循环(蒙特卡罗循环)中执行spmd,但是当我以这种方式使用并行化时,我看不到性能提升。
非常感谢你的帮助。
答案 0 :(得分:0)
MATLAB关于随机生成器(http://www.mathworks.com/help/matlab/math/creating-and-controlling-a-random-number-stream.html)的网页声明只有两个流/生成器可以有多个流。这两个期限有限(参见上一个链接的表格)。
BUT !!!可以播种默认生成器(mt19937ar
)以获得不同的结果:)
因此,您可以做的是从mrg32k3a
开始,在每个工作者中获取一个随机数,然后使用此随机数和工作人员索引为mt19937ar
生成器播种。
E.g。
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
),以便进行更复杂的播种。