parfor
ループ反復が独立していることの確認
for
ループを parfor
ループに変換したときにエラーが表示された場合は、parfor
ループの反復が独立していることを確認します。parfor
ループの反復には "確定的な順序がない" 一方で、for
ループは "逐次的"です。また、parfor
ループの反復は並列プール内の異なる MATLAB® ワーカー上で実行されるため、反復間で情報が共有されません。したがって、parfor
ループの反復は前の反復結果に依存してはなりません。この規則の唯一の例外は、リダクション変数の使用によりループ内に値を累積する場合です。
次の例では、左側で for
ループを、右側では parfor
ループを使用して同等な結果を得ています。この例を MATLAB コマンド ウィンドウで試してください。
clear A for i = 1:8 A(i) = i; end A A = 1 2 3 4 5 6 7 8 | clear A parfor i = 1:8 A(i) = i; end A A = 1 2 3 4 5 6 7 8 |
A
の各要素はそのインデックスと等しくなっています。parfor
ループは機能しますが、これは各要素がインデックス付きのループ変数のみにより決定され、他の変数には依存しないからです。独立したタスクを含む for
ループは、parfor
ループの最適な候補です。
メモ
既定では、並列プールがまだ起動していない場合、parfor
は自動的にワーカーの並列プールを起動します。並列基本設定が適切に設定されている場合、parfor
は既定のクラスター プロファイルを使用してプールを作成します。
この例では、for
ループとまったく同様に、parfor
ループの後で配列要素がクライアント ワークスペース内で使用可能になります。
ここで、インデックスが付いていない変数か、またはインデックスがループ変数 i
に依存しない変数をループ内で使用します。以下の例を実行し、その後 d
および i
の値を確認します。
clear A d = 0; i = 0; for i = 1:4 d = i*2; A(i) = d; end A d i A = 2 4 6 8 d = 8 i = 4 | clear A d = 0; i = 0; parfor i = 1:4 d = i*2; A(i) = d; end A d i A = 2 4 6 8 d = 0 i = 0 |
両方の例で A
の要素は同じですが、d
の値は異なってます。for
ループでは反復が逐次実行されるため、実行後の d
はループの最終反復で保持していた値を取ります。しかし、parfor
ループでは反復が並列実行されるため、ループの終わりで d
に明確な値を代入することは不可能です。この状況はループ変数 i
にも当てはまります。したがって、parfor
ループの動作は、ループ外の変数 d
と i
に影響しないように定義されています。これらの値はループの前後で不変です。parfor
ループ内の変数が独立でない場合、for
ループ内のものとは異なる結果になることがあります。つまり、parfor
ループでは、それぞれの反復が他の反復とは独立している必要があります。parfor
ステートメントに続くすべてのコードは、ループ反復の順序に依存していてはなりません。
コード アナライザーは、ループの反復が依存的かどうかの診断に役立ちます。例のコードでは、反復が前の反復によって定義されています。
parfor k = 2:10 x(k) = x(k-1) + k; end
ただし、他の場合ではコード アナライザーは依存関係をマークできません。
その他一般的な parfor
の問題のヘルプについては、入れ子にされた parfor ループおよび for ループ、およびその他の parfor の要件を参照してください。
参考
関連する例
- parfor を使用するタイミングの決定
- for ループから parfor ループへの変換
- 入れ子にされた parfor ループおよび for ループ、およびその他の parfor の要件
- parfor ループ内の変数のトラブルシューティング
- リダクション変数