2

Mersenne Twister( MT) 乱数ジェネレーターの CUDA の実装は、スレッド/ブロック256および200ブロック/グリッドの最大数に制限されています。つまり、スレッドの最大数は です51200

そのため、MT を使用するカーネルを で起動することはできません。

kernel<<<blocksPerGrid, threadsPerBlock>>>(devMTGPStates, ...)

どこ

int blocksPerGrid = (n+threadsPerBlock-1)/threadsPerBlock;

およびnはスレッドの総数です。

MTforを使用する最良の方法は何threads > 51200ですか?

blocksPerGridとに定数値を使用する場合の私のアプローチthreadsPerBlock、たとえば<<<128,128>>>、カーネルコードで次を使用します。

__global__ void kernel(curandStateMtgp32 *state, int n, ...) { 

    int id = threadIdx.x+blockIdx.x*blockDim.x;

    while (id < n) {

        float x = curand_normal(&state[blockIdx.x]);
        /* some more calls to curand_normal() followed
           by the algorithm that works with the data */

        id += blockDim.x*gridDim.x; 
    }
}

これが正しい方法なのか、MT のステータスに望ましくない影響を与える可能性があるのか​​、よくわかりません。

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

4

2 に答える 2

3

CURAND のドキュメントを注意深く徹底的に読むことをお勧めします。

MT API は、1 ブロックあたり 256 スレッド、最大 64 ブロックを使用して数値を生成する場合に最も効率的です。

それ以上必要な場合は、さまざまなオプションがあります。

  1. 既存の状態セット (つまり、64 ブロック、256 スレッド) からより多くの数値を生成し、それらの数値を必要とするスレッド間でこれらの数値を分配するだけです。
  2. ブロックごとに複数の状態を使用します (ただし、これにより、状態セット内の全体的な制限を超えることはできません。単一のブロックの必要性に対処するだけです)。
  3. 独立したシード (したがって、独立した状態セット) を持つ複数の MT ジェネレーターを作成します。

一般的に、あなたが概説したカーネルに問題は見られず、上記の選択肢 1 とほぼ一致しています。ただし、51200 スレッドを超えることはできません。(あなたの例には<<<128, 128>>>16384個のスレッドがあります)

于 2013-10-21T20:32:09.077 に答える