5

次の最小限の例を設定しました。

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);

これにより、10 個の乱数が生成され、 に格納されtます。rngforループでシードを設定するため、常に同じ乱数が確実に生成されます。

に変更forするとparfor異なる結果が得られます。それらは常に再現可能ですが。

parfor を使用してコードを高速化し、for とまったく同じ乱数を取得したい...

4

4 に答える 4

6

わかりました、私は理由を見つけました:

MATLAB は、さまざまな乱数生成アルゴリズムをサポートしています。現在のバージョンの通常の設定では、これは Mersenne Twister です。parfor ループに入ると、これは「複合再帰メソッド」と呼ばれるものに変わります。

'twister'この問題は、ループ内でタイプを明示的に設定することで修正できます。

parfor i = 1:10
    rng(randseedoffset+i, 'twister');
    t{i} = random('unid', 1000);
end
于 2013-06-14T14:55:34.673 に答える
0

これを試して:

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
于 2016-01-25T14:29:17.810 に答える
0

同じジョブで作業しているクラスター内の各ワーカーには、独立した乱数ジェネレーター ストリームがあります。したがって、既定では、プール内の各ワーカーと parfor ループ内の各反復には、一意の独立した乱数のセットがあります。parfor ループの後続の実行では、異なる数値が生成されます。

parfor ループでは、反復を実行する順序を制御することも、どのワーカーがどの反復を実行するかを制御することもできません。そのため、乱数発生器をリセットしても、parfor ループは同じ値を異なるシーケンスで生成できます。

ループが実行されるたびに parfor ループで同じ乱数のセットを再現するには、反復ごとに特定のサブストリームを割り当てて乱数の生成を制御しなければなりません。

まず、サブストリームをサポートするジェネレーターを使用して、使用するストリームを作成します。ストリームを parallel.pool.Constant として作成すると、すべてのワーカーがストリームにアクセスできるようになります。

sc = parallel.pool.Constant(RandStream('Threefry'))

parfor ループ内では、ループ インデックスによってサブストリーム インデックスを設定できます。これにより、どのワーカーがその反復を実行するか、または反復がどのシーケンスで実行されるかに関係なく、各反復が特定の乱数セットを使用することが保証されます。

r = zeros(1,16);
parfor i = 1:16
    stream = sc.Value;        % Extract the stream from the Constant
    stream.Substream = i;
    r(i) = rand(stream);
end

https://www.mathworks.com/help/parallel-computing/repeat-random-numbers-in-parfor-loops.html

于 2021-01-11T04:34:41.763 に答える