1

CUDAについて少し疑問があります。おそらく、それらはばかげた質問に思えるかもしれません。申し訳ありません。

GPU で変数 (たとえば、N 個の要素を持つ配列alphaなど) を宣言し、メモリを解放せずにその値をグローバル関数に割り当てると、この変数は他の後続のグローバル関数で使用できるはずですよね?cudaMalloc((void**)&alpha, N * sizeof(double))

さらに、GPU でスカラー変数を計算し、GPU の複数のグローバル関数間で共有することは可能ですか (または推奨されますか)、それとも CPU からの引数として毎回渡す方がよいでしょうか?

ご清聴ありがとうございました。

4

3 に答える 3

1

GPU で変数 (たとえば、N 個の要素を持つ配列 alpha cudaMalloc((void**)&alpha, N * sizeof(double))) を宣言し、メモリを解放せずにその値をグローバル関数に割り当てると、この変数は他の連続するグローバル関数で使用できるはずですよね?

cudaMalloc()グローバル関数 (カーネル) から呼び出すことはできません。ホスト機能です。malloc()newをカーネルで使用できますが、非効率的です。

複数のカーネルで同じ配列を使用できます。たとえば、異なるカーネルで複数の計算ステップを実行できます。

さらに、GPU でスカラー変数を計算し、それを GPU の複数のグローバル関数間で共有することは可能ですか (または推奨されますか)、それとも CPU からの引数として毎回渡す方がよいでしょうか?

定数を引数としてカーネルに渡すと、すべてのスレッド間で非常に効率的に共有されます。そのため、通常、CPU でパラメーターを計算してカーネルに渡す方がはるかに効率的です。

スカラーの作成に多くの並列計算が必要な場合は、別のカーネルで計算し、それをホストに戻してから、次のカーネルに引数として渡すのが最善です。代替手段は、コードの複雑さを増すだけで、パフォーマンス上の利点はありません。

スカラーに必要な計算がほとんどない場合、カーネルで計算しても意味がありません。また、カーネルでブロックが起動される順序について保証がないことを覚えておいてください。そのため、カーネルで別のコード パスを作成してスカラーを設定し、コストのかかるスレッド インデックスのテストと同期を行って、スカラーにして、すべてのスレッドで利用できるようにします。

于 2012-12-29T20:15:12.057 に答える
1

はい、割り当てられたグローバル メモリに値を書き込むと、そのメモリを解放するまで、それらの値は、カーネルの呼び出し間であっても永続的です。

スカラー変数 (定数) へのアクセスに関しては、グローバル メモリに格納してそこから読み取るよりも、グローバル カーネルの起動にパラメーターとして渡す方が適切です。グローバル メモリへのアクセスはコストがかかるため、読み取る必要があるたびにグローバル メモリからそのスカラーをロードする必要がなくなります。

于 2012-12-29T20:06:54.807 に答える
1

質問が正しければ、配列を割り当てて、GPU のグローバル カーネル関数に配列を入力し、別のカーネル呼び出しでその配列の値を処理します。

割り当てられた配列を解放しない限り、その値はグローバル メモリに残ります。したがって、それを実行して、同じ配列を CPU にコピーし直すことなく処理できます。複数のカーネル呼び出し間でジョブを分割すると、実行時間の制限がある場合やカーネル関数の 1 つがライブラリにある場合に便利です。しかし、他のほとんどの場合、1 回の関数呼び出しですべてのジョブを実行する方がよいようです。

また、グローバル メモリからスカラー値を読み取るとオーバーヘッドが非常に高くなるため、スカラー値を引数として渡す方がよいようです。

于 2012-12-29T20:09:32.353 に答える