0

データをCudaに送信して処理するプロセスがあり、特定の基準に一致するデータを出力します。問題は、出力された配列のサイズがわからないことが多いことです。私に何ができる?

数百行のデータを送信し、Cuda で 2 万以上の方法で処理します。結果が私が持っているいくつかのルールと一致する場合、結果を保存したいと思います。問題は、Cudaでリンクリストを作成できないことです(できるかどうか教えてください)、カードのメモリが小さいため、ゼロコピーを使用してCudaにホストメモリに直接書き込むことを考えていました. これでメモリ サイズの問題は解決しますが、unknown に対処する方法はまだありません。

私の最初のアイデアは、可能な最大の結果を把握し、そのサイズの配列をmallocすることでした。問題は、それが巨大になり、ほとんどが使用されないことです (800 行のデータ * 20K の可能な結果 = 配列内の 1600 万のアイテム..これはありそうにありません)。

Cudaで可変サイズの配列を処理するより良い方法はありますか? 私はプログラミングに慣れていないので、理想的にはそれほど複雑ではないものになるでしょう(ただし、そうであれば、喜んで学びます)。

4

3 に答える 3

1

カーネル コードで使用するヒープ メモリの割り当てmallocは、コストのかかる操作です (これにより、CUDA ドライバーがカーネルをカスタム ヒープ サイズで初期化し、カーネル内でメモリ操作を管理するように強制されます)。

一般に、CUDA デバイスのメモリ割り当ては、プログラム パフォーマンスの主なボトルネックです。一般的な方法は、必要なすべてのメモリを最初に割り当て、できるだけ長く再利用することです。

十分な大きさのバッファを作成し、メモリ割り当ての代わりに使用できると思います。最悪の場合、このバッファからのメモリ割り当てを実装するためにラップできます。単純な単純なケースでは、配列内の最後の空きセルを保持して、次回データを書き込むことができます。

于 2012-06-18T18:53:43.443 に答える
0

はい、CUDA とすべての GPGPU のボトルネックは、ホストからデバイスへの転送とその逆です。

ただし、カーネルでは、常にすべての既知のサイズを使用してください。カーネルは malloc を実行してはいけません... プラットフォームの概念からすると非常に奇妙です。CUDA カーネルに「for」ループがある場合でも、約 20 回のアプローチが最適であると考えてください。本当に複雑なアルゴリズムを実行しているに違いありません。並列プラットフォームで本当に必要ですか? そうしないとどんな問題が発生するか信じられないでしょう)))

バッファリングされたアプローチを使用します。CUDA要件(読み取り->ハードウェア)にさらに依存するバッファサイズ、次に配列に依存するバッファサイズを決定します。ループ内でカーネルを呼び出し、そこからデータをアップロード、処理、取得します。1 つ、データの配列が終了し、最後のバッファーがいっぱいになりません。各バッファのサイズを単一の値 (int へのポインタなど) として渡し、各スレッドがそのスレッド ID と比較して、値を取得できるかどうか、または範囲外になるかどうかを判断できます。最後のブロックだけが発散します。

于 2016-01-15T19:25:39.347 に答える
0

便利なリンクは次のとおりです: https://devblogs.nvidia.com/parallelforall/using-shared-memory-cuda-cc/

共有メモリを使用して、カーネル関数で次のようなことができます。

__global__ void dynamicReverse(int *d, int n)
{
  extern __shared__ int s[];
  .....
}

ホストでカーネル関数を呼び出し、3 番目のパラメーターに共有メモリ サイズを正確に指定すると、次のようになりますn*sizeof(int)dynamicReverse<<<1,n,n*sizeof(int)>>>(d_d, n);

また、可能であれば、より多くのカーネル関数に巨大なカーネル関数を分割し、コードを減らして実行しやすくすることをお勧めします。

于 2016-07-08T21:37:59.567 に答える