2

動的並列処理を使用して、CUDA のアルゴリズムを改善しようとしています。私の元の CUDA ソリューションでは、すべてのスレッドが各ブロックに共通の数値を計算します。私がやりたいことは、スレッドが共通の値を 1 回だけ計算する粗い (または低解像度) カーネルを最初に起動することです (すべてのスレッドが 1 つのブロックを表す場合のように)。次に、各スレッドは 1 ブロック (16x16 スレッド) の小さなグリッドを作成し、共通の値を渡す子カーネルを起動します。理論的には、多くの冗長な操作を節約できるため、高速になるはずです。しかし、実際には、ソリューションの動作が非常に遅く、その理由はわかりません。

これは非常に単純化されたコードであり、単なるアイデアです。

__global__ coarse_kernel( parameters ){
    int common_val = compute_common_val();
    dim3 dimblock(16, 16, 1);
    dim3 dimgrid(1, 1, 1);
    child_kernel <<< dimgrid, dimblock >>> (common_val, parameters);

}

__global__ child_kernel( int common_val, parameters ){
    // use common value
    do_computations(common_val, parameters);
}

child_kernels の量は多く、スレッドごとに 1 つあり、約 400x400 スレッドが必要です。私が理解していることから、GPU はこれらすべてのカーネルを並行して処理する必要がありますよね?

または、子カーネルはどういうわけか順番に処理されますか?

私の結果は、パフォーマンスが元のソリューションよりも 10 倍以上遅いことを示しています。

4

1 に答える 1

3

親または子のカーネルの起動にはコストがかかります。子カーネルが多くの並列処理を抽出せず、非並列の対応するものに対してあまり利点がない場合、子カーネルの起動オーバーヘッドによってわずかな利点が相殺される可能性があります。

数式ではto、子カーネルを実行するためのオーバーヘッド、teその実行時間、およびts動的並列処理の助けを借りずに同じコードを実行する時間とします。動的並列処理の使用による高速化は ですts/(to+te)。おそらく(しかし、これはあなたのコードからは想像できません)te<tsしかしte,ts<<to、それts/(to+te)は約(ts/to)<1であり、スピードアップではなくスローダウンを観察します。

于 2014-01-08T22:10:23.800 に答える