Intel® FPGA SDK for OpenCL™: ベスト・プラクティス・ガイド

ID 683521
日付 12/08/2017
Public
ドキュメント目次

7.3.2. ローカルメモリーへのデータの事前ロード

ローカルメモリーはグローバルメモリーよりもかなり小さいですが、スループットが大幅に向上し、レイテンシーが大幅に減少します。グローバル・メモリー・アクセスとは異なり、カーネルはパフォーマンス上のペナルティーなしにランダムにローカルメモリーにアクセスできます。 カーネルコードを構造化するときは、グローバルメモリーに順番にアクセスし、そのデータをオンチップローカルメモリーにバッファーリングしてからカーネルが計算に使用します。

Intel® FPGA SDK for OpenCL™オフライン・コンパイラーは、FPGAのオンチップメモリー​​ブロックにOpenCL™ローカルメモリーを実装しています。オンチップメモリー​​ブロックには2つの読み出しポートと書き込みポートがあり、OpenCLカーネルの動作周波数の2倍の動作周波数でクロックすることができます。このクロック周波数を2倍にすることで、メモリーを二重ポンプ」にすることができ、同じメモリーから2倍の帯域幅が得られます。その結果、各オンチップメモリー​​ブロックは最大4つの同時アクセスをサポートします。

理想的には、各バンクへのアクセスは、バンクのオンチップメモリー​​ブロックにわたって均一に分散される。 1クロックサイクルでオンチップメモリー​​ブロックへの同時アクセスは4回しかできないため、アクセスを分散することでバンクの競合を回避できます。

このバンキング設定は通常有効です。ただし、オフライン・コンパイラーは、多数のバンクに対応するために複雑なメモリーシステムを作成する必要があります。多数のバンクが調停ネットワークを複雑にし、システム全体のパフォーマンスを低下させる可能性があります。

オフライン・コンパイラーはFPGAのオンチップメモリー​​ブロックにあるローカルメモリーを実装するため、オフライン・コンパイラーはコンパイル時にローカル・メモリー・システムのサイズを選択する必要があります。オフライン・コンパイラーがローカル・メモリー・システムのサイズを決定する方法は、OpenCLコードで使用されるローカルデータ型によって異なります。

ローカルメモリーアクセスの最適化

ローカルメモリーアクセスの効率を最適化するには、次のガイドラインを考慮してください。

  • ループアンローリングなどの特定の最適化手法を実装すると、より多くの同時メモリーアクセスが発生する可能性があります。
    注意:
    メモリーアクセスの数を増やすと、メモリーシステムが複雑になり、パフォーマンスが低下する可能性があります。

  • 可能であれば、カーネル内の固有のローカルメモリーアクセス数を4以下に制限することで、ローカルメモリーサブシステムを単純化してください。

    ローカル・メモリー・システムへのメモリーアクセスが4つ以下の場合、最大のローカルメモリーパフォーマンスを達成します。特定のメモリーシステムへのアクセス回数が4より大きい場合、オフライン・コンパイラーは、メモリーシステムのオンチップメモリー​​ブロックをバンク構成に配置します。

  • 関数スコープのローカルデータがある場合、オフライン・コンパイラーは、コンパイル時に関数本体内で定義したローカルデータの静的なサイズを指定します。ローカルメモリーを定義するには、オフライン・コンパイラーにメモリーを必要なサイズに設定し、2の累乗に最も近い値に切り上げます。

  • __localカーネル引数を指すポインターの場合、ホストはclSetKernelArg呼び出しによって実行時に動的にメモリーサイズを割り当てます。ただし、オフライン・コンパイラーはコンパイル時にこれらの物理メモリーサイズを設定する必要があります。

    デフォルトでは、 __localカーネル引数のポインターは16 KBです。割り当てサイズは、ポインター宣言にlocal_mem_size属性を含めることで指定できます。

    注: clSetKernelArg呼び出しは、コンパイル時に物理的に割り振られたデータサイズよりも小さいデータサイズを要求できますが、決してそれより大きいサイズにはなりません。

  • ローカルメモリーにアクセスする場合、可能な限り単純なアドレス計算を使用し、必須ではないポインター演算を避けてください。

    インテル® は、オフライン・コンパイラーが静的コード解析を通じてアクセスパターンをより確実に保証できるようにすることにより、FPGAリソースの使用率を削減し、ローカルメモリー効率を向上させるために、このコーディング・スタイルを推奨しています。複雑なアドレス計算とポインター演算を使用すると、オフライン・コンパイラーがデータの異なる部分を表す独立したメモリーシステムを作成するのを防ぐことができ、エリア使用量が増加し、実行時パフォーマンスが低下します。

  • 可能であれば、メモリーへのポインターの格納は避けてください。記憶されたポインターは、しばしばポインターがメモリーから引き出されたときに、アクセスされたデータセットを静的なコンパイラー分析が決定することを防止します。メモリーへのポインターの格納は、ほとんど常に最適ではないエリアとパフォーマンスの結果につながります。

local_mem_size属性の使用法については、 インテル® FPGA SDK for OpenCL™ プログラミング・ガイドローカルメモリーのポインターサイズの指定を参照してください。