アプリケーションによっては、ストリーム (スレッドごとに 1 つのストリーム) がオーバーラップするかどうかを考慮せずに LCG を使用することに注意する必要があります。LCG を使用してリープフロッグを実装することもできますが、その場合、シーケンスが繰り返されないようにするために、十分に長い期間の LCG が必要になります。
リープフロッグの例は次のとおりです。
template <typename ValueType>
__device__ void leapfrog(unsigned long &a, unsigned long &c, int leap)
{
unsigned long an = a;
for (int i = 1 ; i < leap ; i++)
an *= a;
c = c * ((an - 1) / (a - 1));
a = an;
}
template <typename ValueType>
__device__ ValueType quickrand(unsigned long &seed, const unsigned long a, const unsigned long c)
{
seed = seed * a;
return seed;
}
template <typename ValueType>
__global__ void mykernel(
unsigned long *d_seeds)
{
// RNG parameters
unsigned long a = 1664525L;
unsigned long c = 1013904223L;
unsigned long ainit = a;
unsigned long cinit = c;
unsigned long seed;
// Generate local seed
seed = d_seeds[bid];
leapfrog<ValueType>(ainit, cinit, tid);
quickrand<ValueType>(seed, ainit, cinit);
leapfrog<ValueType>(a, c, blockDim.x);
...
}
しかし、その場合、ほとんどの場合、そのジェネレーターの期間はおそらく不十分です。
正直なところ、NAGなどのサードパーティ ライブラリの使用を検討したいと思います。SDK にもいくつかのバッチ ジェネレーターがありますが、この場合、おそらく探しているものではありません。
編集
これは賛成票を投じられたばかりなので、この質問に対する最近の回答で言及されているように、cuRANDが利用可能であり、多くのジェネレーターとディストリビューションを提供していることに言及することは更新する価値があると思います。それは間違いなく最も簡単に開始できる場所です。