サーチ…


parforを使ってループを並列化する

parforを使って、ループの反復を並行して実行することができます:

例:

poolobj = parpool(2);       % Open a parallel pool with 2 workers 

s = 0;                      % Performing some parallel Computations
parfor i=0:9
    s = s + 1;
end
disp(s)                     % Outputs '10'

delete(poolobj);            % Close the parallel pool

注意: parforを直接ネストすることはできません。 parforネストするには、関数fisrt parfor関数を使用し、その関数に第2 parfor parforを追加します。

例:

parfor i = 1:n
[op] = fun_name(ip);
end

function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end

いつparforを使用するか

基本的に、 parforは2つのケースで推奨されています:ループの反復回数が多い(つまり1e10ように)か、各反復に非常に長い時間がかかる場合です(例えばeig(magic(1e4)) )。 spmd場合は、 spmd使用を検討してspmdparforが短い範囲または高速反復のforループより遅い理由は、計算を行うのではなく、すべての作業者を正しく管理するために必要なオーバーヘッドです。

また、多くの関数に暗黙的なマルチスレッドが組み込まれているため、これらの関数を使用すると、シリアルforループよりも効率的でないparforループforます。これは、すべてのコアがすでに使用されているためです。 parforそれはあなたが使用しようとしている機能として、並列通りである一方で、割り当てのオーバーヘッドを持っているので、実際に、この場合の不利益になります。

動作確認するために、次の例を考えてみましょうforのそれとは対照的に、 parfor 。最初に並列プールを開きます。

gcp; % Opens a parallel pool using your current settings

次に、2つの大きなループを実行します。

n = 1000; % Iteration number
EigenValues = cell(n,1); % Prepare to store the data
Time = zeros(n,1);
for ii = 1:n
tic
    EigenValues{ii,1} = eig(magic(1e3)); % Might want to lower the magic if it takes too long
Time(ii,1) = toc; % Collect time after each iteration
end

figure; % Create a plot of results
plot(1:n,t)
title 'Time per iteration'
ylabel 'Time [s]'
xlabel 'Iteration number[-]';

それからfor代わりにparfor使って同じことをしてparfor 。反復ごとの平均時間が増加することがわかります。ただし、 parfor使用可能なすべてのparfor使用しているため、合計時間( sum(Time) )をコンピュータのコア数で割る必要があります。

だから、それぞれの別々の繰り返しを行う時間は、 forを使うforに関してparforを使ってparforますが、合計時間はかなり減ります。

「単一プログラム、複数データ」(SPMD)ステートメントを使用して並列にコマンドを実行する

ループの繰り返しを複数のスレッドに分配する並列for-loop( parfor )とは異なり、1つのプログラムであるmultiple data( spmd )文は一連のコマンドをすべてのスレッドに分配し、各スレッドスレッドはコマンドを実行し、結果を格納します。このことを考慮:

poolobj = parpool(2);    % open a parallel pool with two workers

spmd
    q = rand(3);         % each thread generates a unique 3x3 array of random numbers
end

q{1}             % q is called like a cell vector
q{2}             % the values stored in each thread may be accessed by their index

delete(poolobj)  % if the pool is closed, then the data in q will no longer be accessible

スレッドインデックス(labインデックス、 labindexとも呼ばれます)によって、 spmdブロック中に各スレッドにアクセスできることに注意することが重要です。

poolobj = parpool(2);        % open a parallel pool with two workers

spmd
    q = rand(labindex + 1);  % each thread generates a unique array of random numbers
end

size(q{1})                   % the size of q{1} is 2x2
size(q{2})                   % the size of q{2} is 3x3

delete(poolobj)              % q is no longer accessible

どちらの例でも、 q複合オブジェクトであり、コマンドq = Composite()で初期化することができます。複合オブジェクトは、プールの実行中にのみアクセス可能であることに注意することが重要です。

バッチコマンドを使用してさまざまな計算を並行して実行する

MATLABでマルチスレッドを使用するには、 batchコマンドを使用できます。 Parallel Computingツールボックスがインストールされている必要があります。

時間のかかるスクリプトの場合、たとえば、

for ii=1:1e8
   A(ii)=sin(ii*2*pi/1e8);
end

これをバッチモードで実行するには、以下を使用します。

job=batch("da")

これにより、MATLABをバッチモードで実行できるようになり、その間にMATLABを使用してバッチ処理を追加するなどの作業を行うことができます。

ジョブを完了して配列Aをワークスペースにロードした後に結果を取得Aには:

load(job, 'A')

最後に、「 ホーム 」→「 環境 」→「 パラレル 」→「モニタージョブ」から「モニタージョブGUI」を開き、 ジョブを削除します。

delete(job)

バッチ処理用の関数をロードするには、次のステートメントを使用します。ここで、 fcnは関数名、 Nは出力配列の数、 x1...xnは入力配列です。

 j=batch(fcn, N, {x1, x2, ..., xn})


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow