コードをベクトル化するときのデータの依存関係による競合

1 回の繰り返しから同じループの将来の繰り返しにフィードバックする結果が得られるループは、データの依存関係による競合があると言います競合している値は、配列要素や累算のようなスカラの場合があります。

データの依存関係による競合があるループは、完全に最適化されない場合があります。配列やポインタが関係するデータの依存関係を検出するに、各ループのネストで使用されている配列を広範囲に解析する必要があります。さらに、ループ内で使用され格納される配列の次元と共にオフットおよび要素へのアクセスのストライドを調べる必要があります。配列の使用や格納がループの異なる繰り返しのときにオーバーラップしている可能性がある場合は、データの依存関係の問題が存在します。オペレーションのベクタ順序によって結果が変化する可能性がある場合は、ルーを安全にベクトル化することはできません。このような場合は、コンパイラによって問題が検出され、ループが元の形式のまま残されるかルーの部分的なベクトル化が実行されます。最適なパフォーマンスを得るには、このようなデータの依存関係をコードから取り除く必要があります。

Example 3 に示すループでは、ループの最初にある a[i-2] への参照が、ループの最後の a[i] への格納と競合しています。このループをベクトル化した場合、ベクトル化を行わない場合に得られる結果と異なる結果が得られるので、これは元の形式のままにします。

Example 3.  ベクトル化不可能なデータの依存関係

float a[99], b[99], t;
int i;
for (i = 3; i < 99; i++)
{
    t = a[i-1] + a[i-2];
    b[i] = t + 3.0 + a[i];
    a[i] = sqrt(b[i]) - 5.0;
};

他の配列の添え字による情報は、依存関係の解析の一部として使用されます。配列 a の参照のベクタでない添え字が等しくなることはないので、Example 4 のループはベクトル化されます。nn+1 に等しくなく、繰り返しの間にフィードバックが生じることがないため、これらが等しくなることはありません。配列 a の参照は配列の 2 つの異なる部分を使用しているので、データは共有されません。

Example 4.  ベクトル化可能なデータの依存関係

float a[99][99], b[99], c[99];
int i, n;
...
for (i = 1; i < 99; i++)
{
  a[n][i] = a[n+1][i-1] * b[i] + c[i];
}

Show/hide関連項目

Copyright © 2010-2011 ARM. All rights reserved.ARM DUI 0472EJ
Non-ConfidentialID081711