我觉得有必要详细说明这一点。不要在parfor
循环中重置种子,而且不要并行使用 Mersenne Twister 算法(你会得到很差的统计独立性结果)。
您得到不同结果的原因是由于这些数字应保持的统计属性,算法是不同的。在并行池中,MATLAB 将算法设置为“combRecursive”,并在每个工作人员上设置不同的子流,所以对于随机数,你很高兴。此外,parfor
循环不保证——
- 循环进行的顺序,
- 哪些工人将执行每件作品,或
- 每个工作人员执行了多少次迭代。
因此,在 parfor 循环中生成随机数通常不会返回相同的随机数,即使每个 worker 的状态相同。而是使用 combRecursive 算法的 subStreams 创建一个 RandStream,在 spmd 块中为每个工作人员设置全局流,然后在 spmd 块中为每个工作人员生成数字:
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{:}]';