OpenCL には、複雑な実際のデータを操作する必要があるカーネルがあります。これを処理するために適切なコード行を呼び出す条件ステートメントを中に入れることも、2 つのカーネルを呼び出して条件ステートメントを呼び出し元のコードにプッシュすることもできます。
これは明らかに保守性に悪いですが、パフォーマンスにとって重要ですか?
OpenCL には、複雑な実際のデータを操作する必要があるカーネルがあります。これを処理するために適切なコード行を呼び出す条件ステートメントを中に入れることも、2 つのカーネルを呼び出して条件ステートメントを呼び出し元のコードにプッシュすることもできます。
これは明らかに保守性に悪いですが、パフォーマンスにとって重要ですか?
条件文が 1 つだけの場合、私の経験では、少なくとも NVidia ハードウェアでは、パフォーマンスの違いはまったく無視できます。
基本的に、すべて (またはほとんど) の作業項目が同じコード パスをたどっていれば問題ありません。あなたの場合、取られるコードパスはカーネル引数に依存するため、すべての作業項目は同じパスに従います。
条件がどこにあるかによって少し異なります。最初に読みやすさのためのコード、次にパフォーマンスを測定し、それが問題であることを発見した後のパフォーマンス
例えば。kernel_for_RGB_image と kernel_for_ABGR_image は合理的な使用方法のように思えますが、異なるカーネルを使用して深い内部ループを効果的にアンロールすることは、より大きなメンテナンスの頭痛の種になる可能性があります。
最善の方法は、実際に 2 つの亜種を試してベンチマークすることだと思います。場合によっては、複数の条件付きブロックをコンパイルすると、実行されるのが 1 つだけであっても、パフォーマンスが低下する可能性があります。その理由は GPR (汎用レジスター) です。コンパイラーは、最悪の場合に必要な数のレジスターを割り当てます。
私はそのような解決策を提案することができます: 単一のカーネル関数を持ちますが、コンパイル時の条件付き:
__kernel void work()
{
#if VAR
// one code
#else
// another code
#endif
}
true
次に、条件を変更するときに/false
を設定してカーネルを再コンパイルする必要がありますVAR
。明らかに、コンパイラーにとっては 2 つのカーネルと違いはありませんが、コードの一部がそれらのカーネルで同じであれば、維持する方が良いかもしれません。