自動並列化機能は、ワークシェアリング構造 (PARALLEL DO ディレクティブ) などの OpenMP* のいくつかのコンセプトを取り入れています。ワークシェアリング構造については、「OpenMP によるプログラミング」を参照してください。ここでは、自動並列化について説明します。
次の場合、ループは並列化が可能です。
ループがコンパイル時にカウント可能な場合。つまり、ループの実行回数(ループ反復回数)を表す式が、ループに入る直前に生成されることを意味しています。
FLOW (WRITE の後の READ)、OUTPUT (WRITE の後の WRITE)、または ANTI (READ の後の WRITE)ループ・キャリー・データ依存性がない場合。同じメモリの場所が、ループの異なる反復で参照されるときに、ループ・キャリー・データ依存が起こります。コンパイラの判断で、推測されたループキャリー依存性がランタイム依存性のテストで解決されると、ループは並列化されることがあります。
コンパイラは、コンパイル時に定数ではないループ・パラメータを持つ parallel for ループで、実行するメリットを検証するためにランタイム・テストを生成します。
次のコーディング・ガイドラインにより自動パラレライザの威力と効率を強化することができます。
可能な限りループの最大繰返し回数を明記します。 特に最大繰返し回数が既知でローカル変数にループ引数を保存する場合には定数を使用します。
コンパイラがキャリー依存データと判断する可能性のある構造 (プロシージャ呼び出し、不明瞭な間接参照、グローバル参照など) をループ本体内に配置しないでください。
想定されたデータ依存を一義化するには、!DEC$ PARALLEL ディレクティブを挿入します。
スレッド間の共用で生じるオーベーヘッドを正当化するには、適切ではない動作を含むループの前に !DEC$ NOPARALLEL ディレクティブを挿入します。
自動並列化の処理では、コンパイラは次のステップを実行します。
データフローの解析 ---> ループの分類---> 依存性の解析 ---> 高度な並列化 --> データのパーティショニング ---> マルチスレッド・コードの生成
これらのステップには次のものが含まれます。
データフローの解析: プログラムを通してデータのフローを計算します。
ループの分類: しきい値解析で示されるように 正確さと効率に基づいて並列化のループの候補を決定します。
依存性の解析: 各ループのネストで参照における依存性の解析を計算します。
高度な並列化:
- 依存性のグラフを解析し、並列で実行できるループを決定します。
- ランタイムの依存性を計算します。
データのパーティショニング: SHARED、 PRIVATE、および FIRSTPRIVATE のアクセスのタイプに基づいて、データ参照とパーティションを検査します。
マルチスレッド・コードの生成:
- ループのパラメータを修正します。
- スレッドタスクごとに入口/出口を生成します。
- スレッド生成と同期化の並列ランタイム・ルーチンへの呼び出しを生成します。