説明
重要: 配列変数では、使用できる属性は 1 つのみです。XCL_ARRAY_RESHAPE 属性では多次元配列がサポートされますが、1 つの属性で再形成できるのは 1 つの次元のみです。
この属性は、配列分割と垂直配列マップを組み合わせます。
XCL_ARRAY_RESHAPE 属性は、配列を複数の小型の配列に分割する XCL_ARRAY_PARTITION の効果と、ビット幅を増やして配列の要素を連結する操作を組み合わせたものです。これにより、使用されるブロック RAM の数を削減すると共に、データへの並列アクセスを実現できます。この属性では元の配列よりも要素数が少なくビット幅の広い配列が作成され、1 クロック サイクルでアクセスできるデータ量が増加します。
次のようなコードがあるとします。
void foo (...) {
int array1[N] __attribute__((xcl_array_reshape(block, 2, 1)));
int array2[N] __attribute__((xcl_array_reshape(cycle, 2, 1)));
int array3[N] __attribute__((xcl_array_reshape(complete, 1)));
...
}
ARRAY_RESHAPE 属性を使用すると、配列が次の図に示すように変換されます。
図 1. ARRAY_RESHAPE
構文
この属性は、配列変数の定義と一緒に指定します。
__attribute__((xcl_array_reshape(<type>,<factor>,
<dimension>)))
説明:
-
<type>
: 次のいずれかの分割タイプを指定します。-
cyclic
: サイクリック分割では、配列が計算ユニットのロジックにより同時にアクセス可能な複数の小型の物理メモリとしてインプリメントされます。各メモリに要素が 1 つずつ配置され、すべての配列に配置されたら最初の配列に戻って、配列が完全に分割されるまでそれが繰り返されます。 -
block
: ブロック分割では、配列が計算ユニットのロジックにより同時にアクセス可能な複数の小型メモリとしてインプリメントされます。メモリ ブロックに配列からの要素がフルになるまで配置され、次のメモリ ブロックに移動してそれが繰り返されます。 -
complete
: 完全分割では、配列を個々の要素に分割します。1 次元配列の場合は、メモリが個々のレジスタに分割されます。デフォルトの<type>
はcomplete
です。
-
-
<factor>
: サイクリック分割では、<factor>
でカーネル コードの元の配列をいくつの物理メモリに分割するかを指定します。ブロック分割では、<factor>
で元の配列から各物理メモリに配置する要素の数を指定します。重要: 完全分割 (complete
) では<factor>
は指定しません。 -
<dimension>
: 分割する次元を指定します。1 ~ <N> の整数を指定します。Vitis コア開発キットでは、N 次元の配列がサポートされ、配列をどの 1 つの次元でも分割できます。
例 1
次の例では、17 個の要素を含む 8 ビット配列 AB[17] を、ブロック マップを使用して 5 つの要素を含む 32 ビット配列に再形成 (分割およびマップ) しています。
int AB[17] __attribute__((xcl_array_reshape(block,4,1)));
ヒント:
<factor>
を 4 に指定すると、配列は 4 つに分割されます。つまり、17 個の要素がビット幅が 4 倍の 5 つの要素を含む配列に再形成されます。この場合、最後の要素 AB[17] は、5 番目の要素の下位 8 ビットにマップされ、5 番目の要素の残りは空になります。例 2
次の例では、2 次元配列 AB[6][4] を次元 [6][2] の配列 1 つに再形成しています。この次元 2 のビット幅は 2 倍です。
int AB[6][4] __attribute__((xcl_array_reshape(block,2,2)));
例 3
次の例では、関数 foo
の 3 次元の 8 ビット配列 AB[4][2][2] を 128 ビット幅は (4×2×2×8) の 1 要素配列 (1 つのレジスタ) に再形成しています。
int AB[4][2][2] __attribute__((xcl_array_reshape(complete,0)));
ヒント: <dimension> を 0 に指定すると、配列のすべての次元が再形成されます。