インテル® C++ コンパイラー 14.0 ユーザー・リファレンス・ガイド
このトピックは、インテル® グラフィックス・テクノロジー向けの IA-32 アーキテクチャーにのみ適用されます。インテル® グラフィックス・テクノロジーはプレビュー機能です。
#pragma offload target(gfx) の後のループまたはループの入れ子構造内部のコードおよび __declspec(target(gfx)) で指定された関数のコードは、ターゲットと CPU 用にコンパイルされます。 ターゲットで実行されるほかのコードから、指定された関数を呼び出し、ターゲットで実行することができます。ターゲットがシステムで利用可能で、if が true と評価された場合、コードはターゲットで実行されます。それ以外の場合は、CPU で実行されます (次の例を参照)。
#pragma offload target(gfx) は #pragma parallel_loop で並列として明示的にマークされた完全入れ子ループの前でのみ指定できます。
インテル® グラフィックス・テクノロジー向けにプログラムしている場合、#pragma offload に次の節を指定できます。
target(gfx) – ターゲットにオフロードされたコードセクションのヘテロジニアス実行に必須の節です。
if (condition) – 条件が true の場合、コードはターゲットでのみ実行されます。
in|out|inout|pin(variable_list: length(length_variable_in_elements))
in, out, or inout – 変数は CPU とターゲットメモリー間でコピーされます。
pin – 変数は CPU とターゲット間で共有されます。データは 4 キロバイトでアライメントする必要があります。
ポインターの length 節を含める必要があります。 この節は、ポインターで参照されている型の要素で、ターゲットとコピーまたは共有するデータのサイズを示します。配列へのポインターでは、サイズは参照されている配列の要素で指定されます。
pin 節は、ターゲットでアクセス可能なメモリーとの間でデータをコピーする代わりに、CPU とターゲット間で同じメモリー領域を共有するため、はるかに高速です。このため、pin 節を使用することで、オフロードのコストは大幅に減ります。 O(N2)) のように比較的小さなデータサイズの大量のワークを実行するカーネルでは、この最適化は重要ではありません。
#pragma parallel_loop [collapse(n)] は、1 つ以上の完全入れ子ループがターゲットのスレッドで並列化されることを示します。
デフォルトでは、コンパイラーはホスト CPU とターゲットの両方で実行するアプリケーションを生成しますが、Qoffload- コンパイラー・オプションを使用して、同じソースコードから CPU のみで実行するアプリケーションを生成することもできます。
unsigned parArrayRHist[256][256],
parArrayGHist[256][256], parArrayBHist[256][256];
#pragma offload target(gfx) if (do_offload) \
pin(inputImage: length(imageSize)) \
out(parArrayRHist, parArrayGHist, parArrayBHist)
#pragma parallel_loop
for (int ichunk = 0; ichunk < chunkCount; ichunk++){
…
}上記の例では、CPU コードが生成され、ランタイムは次の処理を行います。
ターゲットがシステムで利用できるかどうかを判断します。
ターゲットが利用できない場合、または do_offload の評価に失敗した場合、for ループを CPU で実行します。
ポインター inputImage で参照される imageSize * sizeof(inputImage[0]) バイトを固定して、ターゲットメモリーとの間でデータをコピーせずに、そのメモリーをターゲットと共有します。
parArrayRHist、parArrayGHist、および parArrayBHist のターゲットメモリー領域を作成します。
for ループの反復空間を N 個のチャンクに分割します (N は chunkCount 以下)。 N の特定の値の選択はオフロードランタイムによって行われます。ドキュメントで説明されているように、境界やストライドのような反復空間構成や、環境変数で制御できる最大値のような要因に依存します。
それぞれ独自の反復空間チャンクを割り当てた N 個のターゲットスレッドでタスクを作成します。
ターゲットで実行するタスクをキューに入れます。
ターゲットのタスクの実行が完了するのを待ちます。
ターゲットメモリーから CPU メモリーに parArrayRHist、parArrayGHist、および parArrayBHist をコピーして、結果が直ちにすべての CPU スレッドで認識されるようにします。
float (* A)[k] = (float (*)[k])matA;
float (* B)[n] = (float (*)[n])matB;
float (* C)[n] = (float (*)[n])matC;
#pragma offload target(gfx) if (do_offload) \
pin(A: length(m*k)), pin(B: length(k*n)), pin(C: length(m*n))
#pragma parallel_loop collapse(2)
for (int r = 0; r < m; r += TILE_m) {
for (int c = 0; c < n; c += TILE_n) {
…
}
}上の例で、
collapse(2) は、オフロードされたループの入れ子構造の反復空間が r ループと c ループの両方を含む 2 次元で、各ターゲットスレッドに並列実行用の 2 次元の反復空間チャンクが割り当てられることを意味します。
A、B および C は配列へのポインターとして定義されますが、length はポインターによって参照された float 型配列の要素で指定されます。
インテル® コンパイラーは、互換マイクロプロセッサー向けには、インテル製マイクロプロセッサー向けと同等レベルの最適化が行われない可能性があります。これには、インテル® ストリーミング SIMD 拡張命令 2 (インテル® SSE2)、インテル® ストリーミング SIMD 拡張命令 3 (インテル® SSE3)、ストリーミング SIMD 拡張命令 3 補足命令 (SSSE3) 命令セットに関連する最適化およびその他の最適化が含まれます。インテルでは、インテル製ではないマイクロプロセッサーに対して、最適化の提供、機能、効果を保証していません。本製品のマイクロプロセッサー固有の最適化は、インテル製マイクロプロセッサーでの使用を目的としています。インテル® マイクロアーキテクチャーに非固有の特定の最適化は、インテル製マイクロプロセッサー向けに予約されています。この注意事項の適用対象である特定の命令セットの詳細は、該当する製品のユーザー・リファレンス・ガイドを参照してください。 改訂 #20110804 |