Main Content

parfor ループでのオブジェクトおよびハンドルの使用

parfor ループでのオブジェクトの使用

parfor ループとオブジェクトの受け渡しを行う場合、オブジェクトは保存と読み込みに適したものでなければなりません。詳細は、オブジェクトの保存と読み込みのプロセスを参照してください。

第 1 レベルのインデックス付けの制約により、オブジェクトのフィールドをスライスすることはできません。詳細については、スライス化された変数を参照してください。

たとえば、左側のコードでは、インデックス付けが原因でループ内の両方の行で分類エラーが発生します。右側のコードでは、スライス化された出力を回避するために、スライス化された別々の配列をループ内で使用します。そのうえで、ループの完了後に構造体フィールドを割り当てます。

無効有効
parfor i = 1:4
    outputData.outArray1(i) = 1/i;
    outputData.outArray2(i) = i^2;
end
parfor i = 1:4
    outArray1(i) = 1/i;
    outArray2(i) = i^2;
end
outputData = struct('outArray1',outArray1,'outArray2',outArray2);

ハンドル クラス

ハンドル オブジェクトを parfor ループ本体への入力として送信できます。ただし、ループ反復中にワーカー上で行われたハンドル オブジェクトの変更は、クライアントに自動的には伝播されません。すなわち、ループ内に対して行われた変更は、ループを抜けた後に自動的に反映されません。

ループを抜けた後でクライアントに変更を返すには、変更されたハンドル オブジェクトを、parfor ループの出力変数に明示的に代入する必要があります。次の例で、maps はスライス化された入出力変数です。

maps = {containers.Map(),containers.Map(),containers.Map()}; 
parfor ii = 1:numel(maps)
    mymap = maps{ii};   % input slice assigned to local copy
    for jj = 1:1000
        mymap(num2str(jj)) = rand;
    end
    maps{ii} = mymap;   % modified local copy assigned to output slice
end

関数ハンドルを参照するスライス化された変数

ループ インデックスを入力引数に指定して関数ハンドルを直接呼び出すことはできません。この変数をスライス化された入力変数と区別できないためです。ループ インデックス変数を引数に指定して関数ハンドルを呼び出さなければならない場合は、feval を使用します。

次の例では、関数ハンドルと for ループを使用しています。

B = @sin;
for ii = 1:100
    A(ii) = B(ii);
end

これに対応する parfor ループでは、B が関数ハンドルを参照できません。feval を使用してこの問題を回避することができます。

B = @sin;
parfor ii = 1:100
    A(ii) = feval(B,ii);
end

関連するトピック