変数のスレッド固有化は、プログラムの並列化を向上させる上で便利な方法です。しかし、プライベート変数がループの外側で参照される場合には、コンパイラが正しい値を持つことを確認する必要があります。次の例を考えてみましょう。
使用例 3-9 ストアバック変数を使用した並列化ループfor (i=1; i < 1000; i++) { t = 2 * a[i]; /* S1 */ b[i] = t; /* S2 */ } x = t; /* S3 */
この例では、文 S3 で参照されている t の値が、ループで計算される t の最終値です。変数 t がスレッド固有化され、ループの実行が終了したあと、t の正しい値をオリジナルの変数に戻すことが必要になります。このプロセスは「ストアバック」と呼ばれ、最後の繰り返しでの t の値を変数 t のコピーを元の場所に戻すことで実現されます。多くの場合、コンパイラはこれを自動的に行うことができますが、最後の値を容易に計算できない場合があります。
使用例 3-10 ストアバックを使用できないループfor (i=1; i < 1000; i++) { if (c[i] > x[i] ) { /* C1 */ t = 2 * a[i]; /* S1 */ b[i] = t; /* S2 */ } } x = t*t; /* S3 */
正しい実行の場合、文 S3 の t の値は通常、ループの最後の繰り返しでの t の値ではありません。実際には、条件 C1 が真なのは、最後の繰り返しです。一般に、t の最終値の計算は困難である可能性があります。この例のような場合には、コンパイラはループを並列化しません。