pyopencl を使用して、512 x 512 (262,144 ピクセル) の画像で特定のピクセルを見つけています。プログラムを実行し、ピクセルの近隣を既知の近隣グループと比較すると、(512,512) が開始されます。画像合成をしています。カーネル内にピクセルのグループが見つかった場合、残りのカーネルが実行されるのを待ちたくありません。実行中の残りのカーネルをカーネル プログラムで終了する方法はありますか?
ありがとうティム
多数のワークアイテムを含むカーネルをキューに入れると、カーネルはワーク グループとスレッドに分割され、GPU をビジー状態に保ちます。非常に大きなグローバル サイズは、できるだけ多くのスレッドを開始し、古いスレッドが終了したときに新しいスレッドを発行します。そのため、パフォーマンスが良好な最小のグローバル サイズを見つけて、それらの多くを (1 つの大きなものではなく) キューに入れることができますが、以前にキューに入れた結果もチェックすることができます (イベントを使用して、いつ完了したかを知ることができます。メモリを読み戻して結果を取得します)。正しい答えが得られたら、カーネルのキューイングを停止します。
これの代わりに:
queue entire job (say, 4096 x 4906)
行う:
do
{
queue some work (say, 32 x 32)
check if any of the prior work queued is done and check if it got the answer
}
while (no more work OR answer found)
小さいジョブのサイズと、結果をチェックするオーバーヘッドと余分な作業を行うオーバーヘッドとの間の適切なトレードオフを把握する必要があります。
あなたの質問は大きな問題であり、並列処理の問題です。
What to do when one of your parallel threads has already the answer to the problem?
OpenCL では、カーネルの実行を制御できません。ホストレベルでさえありません。そして、これは大きな問題です。ただし、ワークアイテムが互いに切り離されて自由に実行されない場合、完全に並列化されていないため、そうあるべきです。
唯一の解決策は、計算を小さな部分に分割し、それぞれの完了を確認することです。ただし、パーツがすでに非常に小さい場合があります (あなたの場合、512x512 は非常に小さいなど)。
あなたの特定のケースでは、すべて(512x512)を処理し、その後、別のカーネルを使用して 512x512 セットから最終結果を取得します。
最初は、各カーネルが読み取りおよび設定できるある種のグローバルメモリフラグがあると考えました。このアプローチには原子性が必要なため、必ずatomic_
関数を使用してください。
__kernel void t(__global int *Data,
__global int *Flag){
if(atomic_max(*Flag, 0) == 0){
//perform calc on Data
if(PixelsFound){
//Set the flag to +1
*Flag = atomic_inc(*Flag);
}
}
}
コミュニティ、これが機能しないことがわかっている場合は、お気軽にコメントしてください!