OpenCL カーネル

この OpenCL カーネルの説明は、C/C ++ カーネルの情報に基づいたものです。カーネルのパフォーマンスを加速する同じプログラミング手法は、C/C++ と OpenCL カーネルの両方に適用されます。ただし、OpenCL カーネルでは、プラグマの代わりに __attribute 構文が使用されます。使用可能な属性の詳細は、OpenCL 属性 を参照してください。

次のコード例は、Vitis アプリケーション アクセラレーション開発フローの OpenCL カーネルの要素をいくつか示したものです。これは、OpenCL またはカーネル開発の入門用のものではなく、OpenCL および C/C++ カーネル間の主な違いを示すためのものです。

カーネル シグネチャ

C/C++ カーネルでは、カーネルが Vitis コンパイラのコマンド ラインで v++ --kernel オプションを使用すると識別されます。ただし、OpenCL コードの場合は、__kernel キーワードでカーネルが識別されます。1 つの .cl ファイル内で複数のカーネルを定義でき、Vitis コンパイラは --kernel オプションでどのカーネルをコンパイルするか指定している場合を除き、カーネルをすべてコンパイルします。
__kernel __attribute__ ((reqd_work_group_size(1, 1, 1)))
void apply_watermark(__global const TYPE * __restrict input, 
   __global TYPE * __restrict output, int width, int height) {
{
   ...
}
ヒント: 上記のカーネル関数 apply_watermark のコードすべては GitHub の Vitis サンプル リポジトリ内の Global Memory Two Banks (CL) にあります。

上記の例の場合、ウォーターマーク カーネルに inputoutput という 2 つのポインター タイプの引数と、widthheight という 2 つのスカラー タイプの int 引数が含まれています。

C/C++ カーネルの場合、これらの引数は HLS INTERFACE プラグマを使用して見つける必要がありますが、OpenCL カーネルの場合、Vitis コンパイラおよび Vivado HLS でカーネル引数が認識され、必要に応じてポインター引数が m_axi インターフェイスに、スカラー引数が s_axilite インターフェイスにコンパイルされます。

カーネル最適化

カーネルがターゲット プラットフォームのプラグラマブル ロジックで実行されるので、タスクをその環境に最適化することがアプリケーション デザインの重要な要素です。C/C ++ カーネル で説明する最適化手法のほとんどが OpenCL カーネルに適用できます。C/C++ カーネルに使用する HLS プラグマを適用するのではなく、OpenCL 属性 で説明するように __attribute__ キーワードを使用します。次に例を示します。

// Process the whole image 
__attribute__((xcl_pipeline_loop))
image_traverse: for (uint idx = 0, x = 0 , y = 0  ; idx < size ; ++idx, x+= DATA_SIZE)
{
   ...
}

上記の例は、for ループの image_traverse をパイプライン処理して、カーネルのパフォーマンスを改善する必要があります。この場合、ターゲット II は 1 です。詳細は、xcl_pipeline_loop を参照してください。

次のコード例では、ウォーターマーク関数で opencl_unroll_hint 属性を使用して、Vitis コンパイラがループを展開して、レイテンシを削減してパフォーマンスが改善されるようにしています。ただし、この場合、__attribute__ は提案にすぎないので、コンパイラは必要であれば無視できます。詳細は、opencl_unroll_hint を参照してください。

//Unrolling below loop to process all 16 pixels concurrently
__attribute__((opencl_unroll_hint))
watermark: for ( int i = 0 ; i < DATA_SIZE ; i++)
{
   ...
}

どの特定の最適化が OpenCL カーネルでサポートされるかについては、OpenCL 属性 を参照してください。また、これらの最適化をカーネル デザインでどのように適用するかについては、C/C ++ カーネル を参照してください。