MATLAB Language
マルチスレッド
サーチ…
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
使用を検討してspmd
。 parfor
が短い範囲または高速反復の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})