2

私は大きな配列(たとえば512K要素)をGPUに常駐させており、処理する必要があるのはごく一部の要素(たとえば、5Kのランダムに分散された要素-セットS)だけです。どの要素がSに属するかを見つけるアルゴリズムは非常に効率的であるため、集合Sから要素へのポインターまたはインデックスの配列Aを簡単に作成できます。

Sの要素に対してのみCUDAまたはOpenCLカーネルを実行する最も効率的な方法は何ですか?アレイA上でカーネルを実行できますか?これまでに見たすべての例は、連続した1D、2D、または3Dアレイを扱っています。間接参照の1つのレイヤーを導入することに問題はありますか?

4

3 に答える 3

4

CUDAでは、メモリの合体​​が使用される可能性があるため、連続した(ランダムではない)メモリアクセスが推奨されます。ランダムに分散されたインデックスの配列を作成し、スレッドごとにAから1つのインデックスを処理することは、大したことではありません。次のようになります。

__global__ kernel_func(unsigned * A, float * S)
{
    const unsigned idx = threadIdx.x + blockIdx.x * blockDim.x;
    const unsigned S_idx = A[idx];

    S[S_idx] *= 5; // for example...
    ...
}

ただし、S [ランダムアクセス]へのメモリアクセスは非常に遅くなります(これが最も可能性の高いボトルネックになります)。

CUDAを使用する場合は、ブロック/グリッドサイズで多くの実験を行い、スレッドあたりのレジスタ消費を最小限に抑え(マルチプロセッサあたりのブロック数を最大化するため)、Aを並べ替えて最も近いスレッドから最も近いS_indを使用する必要があります...

于 2010-08-15T08:05:10.917 に答える
1

インデックスを並べ替えたり、パフォーマンスの割り当てに役立つ並べ替えられたリストを作成したりする場合、インデックスのクラスターがある場合は、テクスチャメモリを使用してみてください。また、各スレッドの多数の要素に重複してアクセスしている場合は、共有を使用して見つけました。メモリはパフォーマンスを大幅に向上させます。

于 2010-08-15T15:55:34.900 に答える
1

1レベルの間接参照ではまったく問題ありません。私はそれを自分のCUDAコードでかなりの量使用しています。セットSは時間の経過とともに静的なままになる可能性がありますか?もしそうなら、あなたが言ったようにルックアップAを生成することは非常に価値があるかもしれません。

また、テクスチャメモリは、キャッシュの局所性を提供する上であなたの友達になります。使用するテクスチャのタイプ(1D、2D、または3D)は、問題によって異なります。

于 2011-01-18T18:47:20.383 に答える