1

これが明らかな場合は申し訳ありませんが、私は現在c ++とCudaを研究しており、これが可能かどうかを知りたいので、関連するセクションにさらに焦点を当てることができます。

基本的に、私の問題は高度に並列化可能です。実際、現在、複数のサーバーで実行しています。私のプログラムは作業項目(非常に小さなリスト)を取得し、その上でループを実行して、次の3つの決定のいずれかを実行します。

  1. データを保持する(保存する)、
  2. データを破棄します(データは何もしません)、
  3. データをさらに処理します(何をすべきかわからないため、データを変更し、処理するためにキューに再送信します。

これは以前は再帰でしたが、各部分を独立させました。1つのCPUに拘束されることはなくなりましたが、その悪影響として、メッセージが何度も行き来することがあります。CUDAがどのように機能し、どのように作業を送信するかを大まかに理解していますが、CUDAがデバイス自体のキューを管理することは可能ですか?

私の現在の思考プロセスは、c ++ホストでキューを管理し、処理をデバイスに送信した後、結果がホストに返され、デバイスに返送されることでした(以下同様)。それはうまくいくと思いますが、CUDAメモリ自体にキューを置き、カーネルが作業を引き受けて直接そこに送信できるかどうかを確認したかったのです。

CUDAでこのようなことが可能ですか、それともこれを行うためのより良い方法がありますか?

4

1 に答える 1

1

あなたが求めているのは、デバイスで中間結果を維持できるかどうかだと思います。その答えはイエスです。つまり、新しい作業項目をデバイスにコピーし、完成した項目のみをデバイスからコピーする必要があります。まだ決定されていない作業項目は、カーネル呼び出しの合間にデバイスにとどまる可能性があります。

これについては、CUDAスラストを調べてください。Thrustには、変換用の効率的なアルゴリズムがあり、カスタムロジックと組み合わせることができます(Thrustマニュアルで「カーネルフュージョン」を検索してください)。おそらく、処理は変換と見なすことができ、作業項目のベクトルを取得して作成します。 2つの新しいベクトル。1つは保持するアイテム、もう1つはまだ決定されていないアイテムです。

ホストはデバイス上のメモリを認識していますか(または監視できますか)?私の懸念は、GPUオンボードメモリを超え始めたデータをどのように認識して処理するかです。

カーネル内からメモリを割り当てたり解放したりすることは可能ですが、おそらくあまり効率的ではありません。代わりに、cudaMalloc()andなどのCUDA呼び出しを実行してメモリを管理しcudaFree()ます。または、Thrustを使用している場合は、カーネル呼び出し間でベクトルを作成またはサイズ変更します。

この「手動」メモリ管理を使用すると、で使用したメモリの量を追跡できますcudaMemGetInfo()

完了した作業項目をホストにコピーして戻すので、デバイスに残っている作業項目の数、つまりカーネル呼び出しで必要になる可能性のあるメモリの最大量がわかります。

おそらく良い戦略は、各変換のソースベクトルと宛先ベクトルを交換することです。簡単な例として、複数のステップでフィルタリングする一連の作業項目があるとします。ベクトルAを作成し、それを作業項目で埋めます。次に、同じサイズのベクトルBを作成し、空のままにします。フィルタリング後、Aの作業項目の一部がBに移動され、カウントされます。ここで、フィルターを再度実行します。今回は、Bをソース、Aを宛先とします。

于 2012-05-06T06:10:43.573 に答える