ループを展開すると、モデルを完全に並列処理できるようになります。展開するループをマークしておくと、ツールで並列処理を最大限にできるようにインプリメンテションが作成されます。展開するループをマークするには、OpenCL ループに UNROLL 属性を指定します。
__attribute__((opencl_unroll_hint))
または、C/C++ ループで unroll プラグマを使用します。
#pragma HLS UNROLL
詳細は、ループ展開 を参照してください。
この例に適用すると、HLS プロジェクトのスケジュール ビューアーに次のように示されます。
次の図に、パフォーマンスの見積もりを示します。
同じ計算を並列実行することにより、総レイテンシは大幅に改善されて 127 サイクルになり、計算ハードウェアは 4845 個の LUT に増加しています。
for ループを確認すると、各加算が前のループ反復とは完全に別なので、このアルゴリズムが 1 サイクルでインプリメントできないことがわかります。これは、out
変数にメモリ インターフェイスが使用されるからです。Vitis コア開発キットでは、配列に対してデュアル ポート メモリがデフォルトで使用されます。つまり、各サイクルでメモリに書き込むことができるのは、最大 2 つの値までだということです。このため、完全な並列インプリメンテーションを達成するには、次の例に示すように、out
変数をレジスタ内に保持する必要があります。
#pragma HLS array_partition variable= out complete dim= 0
詳細は、 pragma HLS array_partition を参照してください。
この変換の結果は、スケジュール ビューアーで確認できます。
この場合、見積もりは次のようになります。
このコードは、組み合わせ関数としてインプリメントでき、何分の 1 かのサイクルで完了できます。