インテル® Fortran コンパイラー 14.0 ユーザー・リファレンス・ガイド

ベクトル化とループ

このオプションを使用すると、互換マイクロプロセッサーおよびインテル製マイクロプロセッサーの両方で並列化が有効になります。実行ファイルは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーにおいてより優れたパフォーマンスが得られる可能性があります。また、並列化は、/arch (Windows*)、-m (Linux* および OS X*)、[Q]x などの特定のオプションによる影響を受けます。

このオプションを使用すると、インテル製マイクロプロセッサーおよび互換マイクロプロセッサーの両方で、デフォルトの最適化レベルのベクトル化が有効になります。ベクトル化により呼び出されるライブラリー・ルーチンは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーにおいてより優れたパフォーマンスが得られる可能性があります。また、ベクトル化は、/arch (Windows*)、-m (Linux* および OS X*)、[Q]x などの特定のオプションによる影響を受けます。

ループの並列化との相互作用

[Q]parallel[Q]x オプションを組み合わせると、1 回のコンパイルで、自動並列化と自動ループベクトル化の両方を試みることができます。

多くの場合、コンパイラーは、並列化には最外ループ、ベクトル化には最内ループを認識します。しかし、有効であると判断された場合、コンパイラーは同じループに並列化とベクトル化を適用します。

「自動並列化のプログラミング」および「ベクトル化のプログラミングにおけるガイドライン」を参照してください。

まれに、ループ並列化 (自動または OpenMP* 宣言子のいずれかによって) が成功すると、コンパイラーにレポートされるベクトル化されなかったループのメッセージに影響することがあります。例えば、[Q]vec-report2 オプションでは、ループのベクトル化が成功しなかったことが示されます。

ループ本体内の文

ベクトル化可能な演算は、浮動小数点データと整数データとで異なります。

整数配列の演算

ループ本体の文には、算術演算または論理演算 (これも、通常は配列) を使用できます。算術演算は、加算、減算、ABSMIN、および MAX に制限されます。 論理演算には、ビット単位の ANDOR、および XOR の演算子を含んでいます。 データ型は混在させられますが、効率性の低下につながる恐れがあります。

その他の演算

上記の浮動小数点演算と整数演算以外の文は使用できません。上記で説明された以外、ループの本体には、関数呼び出しは使用できません。

データ依存性

データ依存性とは、シリアルループに含まれている各演算の実行順序を制限する関係のことです。ベクトル化によって演算の実行順序が並び替えられるため、自動ベクトライザーでは任意のデータ依存性の解析を自由に使用できなければなりません。

データの依存関係によりベクトル化が妨げられる例を次に示します。この例に示す配列の各要素の値は、前の繰り返しで計算された前後の要素の値により決まります。

例 1: データ依存性を持つループ

subroutine dep(data, n)
  real :: data(n)
  integer :: i
 do i = 1, n-1
    data(i) = data(i-1)*0.25 + data(i)*0.5 + data(i+1)*0.25
  end do 
end subroutine dep
int i;
void dep(float *data){
  for (i=1; i<100; i++){
   data[i] = data[i-1]*0.25 + data[i]*0.5 + data[i+1]*0.25;
  }
}

上記の例に示すループは、ベクトル化できません。これは、現在の要素 DATA(I) への WRITE が直前の要素 DATA(I-1) の使用に依存しており、この要素が直前の反復時にすでに書き込まれ変更されているためです。 このことは、次の例に示すように、配列のアクセスパターンの最初の 2 回の反復を見れば分かります。

例 2: データ依存性を持つループをベクトル化したもの

I=1: READ DATA(0) 
READ DATA(1) 
READ DATA(2) 
WRITE DATA(1) 
I=2: READ DATA(1) 
READ DATA(2) 
READ DATA(3) 
WRITE DATA(2)

このループが示す通常のシーケンスでは、2 回目の反復時に読み込まれる DATA(1) の値は、最初の反復時に書き込まれます。 ベクトル化を行うためには、元のループのセマンティクスを変えることなく、対象となるすべての反復を並列に実行しなければなりません。

例 3: データに依存しないループ
for(i=0; i<100; i++) 
a[i]=b[i]; 
// アクセスパターンは次のとおり
read b[0] 
write a[0] 
read b[1] 
write a[1]

データ依存性の解析

データ依存性の解析とは、2 つのメモリーアクセスの重なり合う条件を見つけることです。その条件は、1 つのプログラムの中で参照を 2 回行うと仮定した場合は、次の 2 つの事項によって規定されます。

配列参照のデータ依存アナライザーは一連のテストとして構成され、時間とスペースコストに加えて性能においても段階的に強化していきます。

いずれかの次元で独立性が認められれば、それによって依存関係が排除できるため、最初は 1 次元ずつ単純なテストをいくつか実行します。宣言されている次元境界を超える恐れのある多次元配列参照は、テストを実施する前に、線形形式に変換できます。

簡単なテストとして、高速最大公約数 (GCD) テストや拡張限界テストなどを使用できます。GCD テストでは、ループ・インデックスの係数の GCD で定数項を均等に等分できない場合、データの独立性が証明されます。拡張限界テストでは、添字式において極値がオーバーラップする可能性があるかどうかをチェックします。

どの単純なテストでも独立性を証明できなかった場合は、最終的に Fourier-Motzkin 法の消去を用いた強力な階層型依存性解法を使用して、すべての次元におけるデータ依存性問題を解決します。

最適化に関する注意事項

インテル® コンパイラーは、互換マイクロプロセッサー向けには、インテル製マイクロプロセッサー向けと同等レベルの最適化が行われない可能性があります。これには、インテル® ストリーミング SIMD 拡張命令 2 (インテル® SSE2)、インテル® ストリーミング SIMD 拡張命令 3 (インテル® SSE3)、ストリーミング SIMD 拡張命令 3 補足命令 (SSSE3) 命令セットに関連する最適化およびその他の最適化が含まれます。インテルでは、インテル製ではないマイクロプロセッサーに対して、最適化の提供、機能、効果を保証していません。本製品のマイクロプロセッサー固有の最適化は、インテル製マイクロプロセッサーでの使用を目的としています。インテル® マイクロアーキテクチャーに非固有の特定の最適化は、インテル製マイクロプロセッサー向けに予約されています。この注意事項の適用対象である特定の命令セットの詳細は、該当する製品のユーザー・リファレンス・ガイドを参照してください。

改訂 #20110804

関連情報


このヘルプトピックについてのフィードバックを送信