インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス
このトピックは、インテル® グラフィックス・テクノロジーをターゲットとする場合にのみ適用されます。
インテル® グラフィックス・テクノロジー・レジスター・ファイル (GRF) は、GRF サブ領域の直接レジスターネーミングと間接アクセスの両方を考慮した、柔軟なアドレッシング・モードを備えるレジスターファイルです。
コンパイラーは可能な場合、コンパイル時に関数またはブロック範囲内の、自動記憶域上の変数と配列を GRF に割り当てようとします。
配列を含む、変数の GRF 割り当てを有効にするには、次の条件が満たされていなければなりません。
変数のサイズが 3K 未満でコンパイル時に既知である。
変数へのポインターがコンパイラーでインライン展開されないほかの関数にエスケープしない (GRF のパフォーマンスの恩恵を受けるためコンパイラーがその関数をインライン展開する場合、ローカル変数からほかの関数にポインターを渡すことはできます)。
複数の変数へのポインターが単一のポインター変数にマージしない。
これらのいずれかの条件が真でない場合、変数または配列はスタックメモリー領域に割り当てられます。
GRF アクセスは、アクセスのレイテンシーが低く命令シーケンスが短いため非常に効率的です。GRF に割り当てられた配列は、定数データのキャッシュに特に役立ちます。ただし、次の点に注意してください。
最も効率良いコードは、GRF 配列への参照を含むループを完全にアンロールして生成されるため、配列へのすべての参照はコンパイル時に既知です。生成されるコードには名前付きレジスターのみ含まれ、GRF への間接アクセスは含まれません。ターゲット・コンパイラーはループの一部をアンロールしますが、ほとんどの場合、#pragma unroll(N) を使用してループをアンロールするよう明示的に指定する必要があります。
さまざまなハードウェアの制限により、コンパイラーは GRF への間接アクセスのベクトル化に失敗することがあります。多くの場合、最も単純でパフォーマンスの高いソリューションは、GRF 配列を参照するループがアンロールされることを保証して間接アクセスを回避することです。
ベクトルアクセスがアライメントされていないとパフォーマンス・ペナルティーが生じるため、GRF 配列へのベクトルアクセスは 32 ビットでアライメントされるようにしてください。コンパイラーは、ベクトル化に際してこの推奨に従おうとしますが、特に短い配列を操作する場合、この可能性を考慮しなければなりません。例えば、intArr[i : VL] のような配列表記セクションでは、i が 8 (4 バイト要素) で割り切れるように保証することが推奨されます。
GRF 上の配列やほかの自動変数に非常に多くのメモリーを割り当てると、コードポイントでレジスターが GRF のサイズ (スレッドあたり 4KB) を超えることがあります。
インテル® グラフィックス・テクノロジー・ドライバーには、レジスターの退避をサポートする JIT コンパイラーが含まれていますが、退避操作はパフォーマンスに悪影響を及ぼし、JIT コンパイラーとドライバーが利用できる退避メモリー領域を超えることがあります。退避操作が起こると、JIT コンパイラーは警告を出力します。退避領域の制限を超えている場合は、ランタイムエラーが起こります。アプリケーションを実行するときは、これらの警告とエラーに注意してください。ローカルの配列サイズとベクトル長を選択するときは GRF のサイズを考慮してください。
デフォルトでは、コンパイラーはインテル® グラフィックス・テクノロジー向けに中間コードを生成します。そして、アプリケーションの実行時に、インテル® グラフィックス・テクノロジー・ドライバーの JIT コンパイラーが、中間コードから実行コードを生成します。
mgpu-arch (Linux*) または Qgpu-arch (Windows*) オプションを使用して、直接実行コードをコンパイルすることもできます。