Main Content

一時変数

"一時変数" とは、インデックス付けされていない直接的代入の対象であり、リダクション変数ではない任意の変数です。次の parfor ループでは、a および d は一時変数です。

a = 0;
z = 0;
r = rand(1,10);
parfor i = 1:10
    a = i;          % Variable a is temporary
    z = z + i;
    if i <= 5
        d = 2*a;     % Variable d is temporary
    end
end

for ループの動作とは異なり、MATLAB®parfor ループの各反復の前に、すべての一時変数をクリアします。反復の独立性を確保するため、一時変数の値をループの 1 つの反復から別の反復に渡すことはできません。したがって、一時変数は parfor ループの本体内で指定されなければなりません。そのため、一時変数の値は各反復で個別に定義されます。

MATLAB は一時変数をクライアントに送り返しません。parfor ループ内の一時変数は、ループ外に存在する同名の変数に影響を与えません。この動作は、通常の for ループとは異なります。

初期化されない一時変数

parfor ループ内の一時変数は、各反復の開始時にクリアされます。一時変数が反復内で設定される前にループ反復がその一時変数を使用するケースを MATLAB が検出することがあります。この場合、MATLAB は実行時エラーではなく静的エラーを発行します。実行時エラーが間違いなく発生する場合、実行の続行を許可することにはほとんど意味がありません。このようなエラーは、特に変数の分類ルールに関して forparfor の間で混同があるため、頻繁に発生します。以下に例を示します。

b = true;
parfor i = 1:n
    if b && some_condition(i)
        do_something(i);
        b = false;
    end
    ...
end

このループは通常の for ループであれば許容されます。しかし parfor ループでは、b はループ内の直接の代入先となっているため、一時変数となります。したがって、この一時変数は各反復の開始時にクリアされるため、if の条件での使用では絶対に初期化されませんparforfor に変更すると、b の値によってループの逐次実行が仮定されます。この場合、bfalse に設定されるまでの i の値が低い場合についてのみ、do_something(i) が実行されます。

リダクション変数としての一時変数

一時変数が初期化されないもう 1 つの一般的な原因となり得るのは、リダクション変数として想定した変数が存在する場合です。しかし、この変数をループ内の他の位置で使用すると、一時変数として分類されます。以下に例を示します。

s = 0;
parfor i = 1:n
    s = s + f(i);
    ...
    if (s > whatever)
       ...
    end
end

s の出現箇所が本体の最初のステートメントの 2 箇所のみである場合、s はリダクション変数として分類されます。しかしこの例では、s はリダクション変数ではありません。リダクション代入以外にも、s > whatever の行で使用されているためです。s は (最初のステートメントにおいて) 代入先であるため、一時変数です。したがって、MATLAB はエラーを発行しますが、リダクションとの関連の可能性も指摘します。

parforfor に変更した場合、リダクション代入外での s の使用は、特定の順序で実行される反復に依存します。parfor ループ内では、その進行過程でリダクション変数の値が "考慮されない" 点が重要です。リダクション値が使用可能になるのは、ループを抜けてからです。

変数 ans

parfor ループの本体内で、変数 ans は一時変数として分類されます。ans には一時変数に対するすべての考慮事項と制約が適用されます。たとえば、parfor ループ内での ans への代入は、ループ外の ans に影響しません。

関連するトピック