質問
私は苦労しこの日のような乱数ジェネレータのスレッドは私のCUDAのコードです。していましたすべてのフォーラムでありこのトピックがイベントカレンダーがまんすることができるようになるほどコードに無い.誰もが知って簡単な方法と思われ デバイス カーネルで呼び出すことができるのを返しませfloat0、1、または整数である私にできる変換はいつも感謝しています。
もう一度、希望の乱数は、カーネルのように、rand()を備えています。
かまいません。
解決
なぜ特別なものが必要なのか理解できません。従来のPRNGは、多かれ少なかれ直接移植する必要があります。 線形合同は正常に機能するはずです。確立しようとしている特別なプロパティがありますか?
他のヒント
興味のある方は、 cuRAND でご利用いただけます。
う議論はこの問いに答える必要Zennaのorginalの要請とは スレッドレベル 実装されます。具体的には、 デバイス機能 この内から呼び出すことができる カーネルまたはスレッド.またoverdidの"大胆に"フレーズだって思ってい答えをこれまでにないものへの対応には何が求められています。
のcuRAND図書館がベストベット。ぜひよろしくお願いしたいという人管理ソリューションを提ホイールでセットをすることで、より適切に利用3rdパーティーのライブラリ)が、高性能、高品質番号ジェネレータは、たっぷりなどの試験を実施する。最情報のでお早めにドキュメンテーションにはGSL図書館の異なる発電機。http://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html
の他の重大なコードでのご利用に最適のアルゴリズムの数学/コンピュータ科学者の地上間のみ全身の弱点が潜んでいる。のメルセンヌツイスター"するといってもいい出来になっている期間繰り返しループ)は10^6000(MT19997アルゴリズムとメルセンヌツイスター2^19997"として予測を算出するのに使用した、Nvidiaの使用は、スレッドレベルのスレッドが同じ反りをスレッドidで通話しています。ペーパーはこちらhttp://developer.download.nvidia.com/compute/cuda/2_2/sdk/website/projects/MersenneTwister/doc/MersenneTwister.pdf.私は実際に取り組んでsomehtingを使用すれば取得しますと正常に動作しまった。Nvidiaは一部の例では、書類のサイトは、現在のCUDA toolkit.
注意:ちなみに私はないので、Nvidiaやかすことを文書化と抽象化設計のためのCUDAではないといけないと思っていく印象に残っています。
アプリケーションによっては、ストリーム(スレッドごとに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 を更新する価値があると考えています。この質問に対するより最近の回答で言及されており、利用可能であり、多くのジェネレータとディストリビューションを提供します。それは間違いなく開始する最も簡単な場所です。
これに最適な方法は、独自のデバイス関数を作成することです。これが
void RNG()
{
unsigned int m_w = 150;
unsigned int m_z = 40;
for(int i=0; i < 100; i++)
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
cout <<(m_z << 16) + m_w << endl; /* 32-bit result */
}
}
32ビットの結果を持つ100個の乱数が得られます。
1〜1000の乱数が必要な場合は、消費の時点または生成の時点で result%1000
を取得することもできます。
((m_z << 16) + m_w)%1000
m_wとm_zの開始値(この例では150と40)を変更すると、毎回異なる結果を得ることができます。それらの1つとして threadIdx.x
を使用できます。これにより、毎回異なる疑似乱数系列が得られます。
rand()関数より2倍速く動作し、素晴らしい動作をすることを付け加えたかった;)
CUDA用の優れたパラレルナンバージェネレーターは見つかりませんでしたが、学術研究に基づいたパラレルランダムナンバージェネレーターを見つけました: http://sprng.cs.fsu.edu/
を試すことができますGPU用Mersenne Twister
これは、SIMD指向のFast Mersenne Twister(SFMT)に基づいており、非常に高速で信頼性の高い乱数ジェネレーターです。乱数ジェネレーターのMarsaglias DIEHARDテストに合格します。