4

Cuda は素晴らしく、私は狂ったように使用していますが、メモリの転送に問題があり、可変量のメモリを取得するより良い方法があるかどうか疑問に思っていたため、彼女の可能性を最大限に活用していません。基本的に、65535 項目配列を Cuda に送信すると、Cuda は各データ項目を約 20,000 の異なる方法で分析し、プログラム ロジックに一致するものがある場合、結果として 30 int リストを保存します。それぞれの異なる組み合わせを分析してから合計を調べるという私のロジックを考えてみてください。合計が探している数値と等しい場合は、結果を保存します(分析された各アイテムの 30 int リストです)。

問題は、65535 (データ配列内のブロック/アイテム) * 20000 (アイテムごとにテストされた組み合わせの合計) = 1,310,700,000 です。これは、すべてのデータが正の一致になる可能性に対処するために、そのサイズの配列を作成する必要があることを意味します (これは非常にありそうもなく、作成するint output[1310700000][30]とメモリが狂っているように見えます)。Cudaがリンクされたリストまたは動的にサイズ設定されたリストに効率的に書き込むことができるかどうかがわからないため、サイズを小さくして処理するブロックを少なくすることを余儀なくされました(このアプローチでは、ブロックを使用してホストメモリに出力を書き込みます* number_of_different_way_tests)。

これを行うより良い方法はありますか?Cuda は、blockid から派生していない空きメモリに何らかの方法で書き込むことができますか? このプロセスを CPU でテストすると、項目配列の 10% 未満しか一致しないため、作業をカーネルに送信するたびに大量のメモリを使用する可能性はほとんどありません。

ps私は上を見ていますが、それはまさに私がやっていることですが、混乱している場合は、別の考え方(私がしていることとは異なりますが、問題を理解するのに十分です)は、20,000個の配列を送信しています(それぞれに65,535個のアイテムが含まれています)、各アイテムを他の配列のピアと追加し、合計が数値(たとえば200〜210)に等しい場合、一致する結果を得るために追加した数値を知りたいです。数値が非常に広い範囲にある場合、すべてが一致するわけではありませんが、私のアプローチを使用すると、その膨大な量のメモリを malloc する必要があります。より少ないメモリを malloc して結果をキャプチャできますか? 私の現在のアプローチは、空きがある限り malloc ですが、効率的ではないより少ないブロックを実行することを余儀なくされています (Cuda がブロックを編成して実行する方法が好きなので、一度にできるだけ多くのブロックとスレッドを実行したい) .

4

1 に答える 1

0

ロジャー・ダールのすばらしい答えによると、探している機能はストリーム圧縮と呼ばれます。

結果をコンパクトな形式で直接保存しようとすると、スレッド間に非常に多くの依存関係が作成される可能性が高いため、スレッドごとに 4 つのソリューションの余地を含む配列を提供する必要がある可能性があり、より少ないデータをコピーして戻すことでパフォーマンスが向上します。カーネルの実行時間が長くなると、ホストが失われます。これに対する例外は、ほとんどすべてのスレッドで解決策が見つからない場合です。その場合、アトミック操作を使用して配列へのインデックスを維持できる場合があります。したがって、見つかったソリューションごとに、配列のインデックスに格納し、アトミック操作を使用してインデックスを増やします。これにはatomicAdd()を使用するのが安全だと思います。結果を格納する前に、スレッドは atomicAdd() を使用してインデックスを 1 つ増やします。atomicAdd() は古い値を返します。

ただし、かなりの数の結果が得られる、より一般的な状況を考えると、最適な解決策は、別の手順として圧縮操作を実行することです。これを行う 1 つの方法は、thrust::copy_if を使用することです。背景については、この質問を参照してください。

于 2012-07-22T20:14:29.303 に答える