インテル® FPGA SDK for OpenCL™プロ・エディション: プログラミング・ガイド

ID 683846
日付 4/01/2019
Public
ドキュメント目次

12.2. カーネルのメモリーシステムをコンフィグレーションするメモリー属性

インテル® FPGA SDK for OpenCL™ は、デザインのコンスタント、ローカルおよびプライベート変数に適用できるカーネルメモリー属性を提供します。それらを使用し、ローカル・メモリー・システムおよびプライベート・メモリー・システムのオンチップ・メモリー・アーキテクチャーをカスタマイズすることが可能です。
重要: これらのローカル・メモリー・カーネル属性は、コンスタント、ローカルまたはプライベート変数にのみ適用してください。
表 13.  ローカルメモリーをコンフィグレーションするためのOpenCLの属性
属性 説明
register ローカル変数が、レジスターのパイプラインを介して伝達される必要があることを指定します。レジスター変数の実装は、FFのみで行うことも、FFとRAMベースのFIFOを組み合わせて行うことも可能です。
memory("impl_type") ローカル変数をメモリーシステムに実装する必要があることを指定します。メモリーカーネル属性を含めることは、ローカル変数を__local修飾子で宣言することと同等です。

オプションで文字列引数を渡し、メモリーの実装タイプを指定することが可能です。impl_typeBLOCK_RAMまたはMLABを指定すると、メモリーはそれぞれ、メモリーブロック (M20Kなど) または、メモリー・ロジック・アレイ・ブロック (MLAB) を使用し実装されます。

numbanks(N)

Nは整数値です。

ローカル変数を実装しているメモリーシステムが、N個のバンクを有する必要があることを指定します。Nは0より大きい2のべき乗の整数値です。
bankwidth(N)

Nは整数値です。

ローカル変数を実装しているメモリーシステムが、Nバイト幅のバンクを有する必要があることを指定します。Nは0より大きい2のべき乗の整数値です。
singlepump ローカル変数を実装しているメモリーシステムをシングルポンピングする必要があることを指定します。
doublepump ローカル変数を実装しているメモリーシステムをダブルポンピングする必要があることを指定します。
numreadports(N)

Nは整数値です。

ローカル変数を実装しているメモリーシステムが、N個の読み出しポートを有する必要があることを指定します。Nは0より大きい整数値です。
numwriteports(N)

Nは整数値です。

ローカル変数を実装しているメモリーシステムが、N個の書き込みポートを有する必要があることを指定します。Nは0より大きい整数値です。
merge("label", "direction") 2つ以上の変数を同じメモリーシステムに実装するように強制します。

labelは任意の文字列です。結合しようとしている変数に同じラベルを割り当てます。

directionwidthもしくはdepthを指定し、メモリーをそれぞれ幅方向または深さ方向のどちらに結合するかを特定します。

bank_bits(b 0 , b 1 , ..., b n ) メモリーシステムを、2nのバンクに分割するよう強制します。b 0 , b 1 , ..., b n は、バンク選択ビットを形成しています。
重要: b 0 b 1 、…、b n はかならず連続する正の整数にしてください。

bank_bits属性なしでnumbanks(n)属性を指定すると、バンク選択ビットはデフォルトで最下位ビット (0、1、…、log2(numbanks)-1) になります。

max_concurrency(N)

メモリーが最大N個のプライベート・コピーを保有し、N回のループの同時反復を常に実行することを指定します。ここでNは、2の累乗に切り上げられます。

(宣言またはアクセスパターンによって) 変数の範囲がループに限定されている場合、この属性を適用します。ループが#pragma max_concurrency M も持っている場合、作成されるプライベート・コピーの数は、min(M,N)になります。

表 14.  メモリー属性のコード例
ユースケース例 構文
レジスターに変数を実装する
int  __attribute__((register)) a[12];
それぞれ8バイト幅の8つのバンクを持つメモリーシステムを実装する
int __attribute__((memory,
                   numbanks(8),
                   bankwidth(8)) b[16];
ダブルポンピングのメモリーシステムを、128バイト幅のバンク1つ、書き込みポート1つ、読み出しポート4つとともに実装する
int __attribute__((memory,
                   numbanks(1),
                   bankwidth(128),
                   doublepump,
                   numwriteports(1),
                   numreadports(4)) c[32];

structのデータメンバーにメモリー属性を適用することも可能です。struct 宣言のstructデータメンバーに属性を指定してください。structのオブジェクトのインスタンス化に属性を適用すると、この属性はstructデータメンバーの宣言で指定された属性を上書きします。以下を例として示します。

struct State { 
  int array[100] __attribute__((__memory__)); 
  int reg[4] __attribute__((__register__)); 
}; 
__kernel void sum(...) { 
  struct State S1; 
  struct State S2 __attribute__((__memory__)); 
  // some uses 
}

オフライン・コンパイラーはS1を、メモリーに実装されるS1.array[100]と、レジスターに実装されるS1.reg[4]の2つの変数に分割します。ただし、S2にはmemory属性が適用されているため、コンパイラーはstruct宣言でオブジェクトS2に適用された属性を無視し、それを分割しません。