2016-12-12 9 views
1

CUDAカーネルを書くときは、シードの更新を保証するために常にこれを行います。乱数ジェネレータシードが推力の度に異なるように保証する方法

__global__ void kernel(curandState *globalState){ 
     curandState *localState; 
     localState = globalState; 
     // generate random number with localState. 
     globalState = localState; 
} 

カーネルを数回実行すると、乱数は常に異なる場合があります。 Generating a random number vector between 0 and 1.0 using Thrust

とtalonmies'答え、私たちは同じファンクタprgで数回実行する必要があり、我々は異なるシードを持っている可能性がどのように: 私の質問は、私たちがこの質問に基づいて乱数を生成するための推力を使用する場合ということです各操作のために? Iは、次のようにコードを書き換えることを試みた:

#include<thrust/random.h> 
#include<thrust/device_vector.h> 
#include<thrust/transform.h> 
#include<thrust/iterator/counting_iterator.h> 
#include<iostream> 
#include<time.h> 

struct prg 
{ 
    float a, b; 
    unsigned int N; 

    __host__ __device__ 
    prg(float _a=0.f, float _b=1.f, unsigned int _N = time(NULL)) : a(_a), b(_b), N(_N) {}; 

    __host__ __device__ 
     float operator()(const unsigned int n) const 
     { 
      thrust::default_random_engine rng(N); 
      thrust::uniform_real_distribution<float> dist(a, b); 
      rng.discard(n); 
      return dist(rng); 
     } 
}; 


int main(void) 
{ 
    const int N = 5; 

    thrust::device_vector<float> numbers(N); 
    thrust::counting_iterator<unsigned int> index_sequence_begin(0); 
    // first operation 
    thrust::transform(index_sequence_begin,index_sequence_begin + N, numbers.begin(),prg(1.f,2.f)); 

    for(int i = 0; i < N; i++) 
    { 
     std::cout << numbers[i] << std::endl; 
    } 
    // second operation 
    thrust::transform(index_sequence_begin,index_sequence_begin + N, numbers.begin(),prg(1.f,2.f)); 

    for(int i = 0; i < N; i++) 
    { 
     std::cout << numbers[i] << std::endl; 
    } 

    return 0; 
} 

第1動作と第2動作は同じ番号を生成します。時差が短いため、この2つの操作で異なる乱数を得るためにコードをどのように変更すればよいのでしょうか?私は操作時間、(1,2、..... 10000、10001、... N)に基づいてシードを割り当てることは可能だと思いますが、それを行うには高価でしょうか?

答えて

4

言い換えれば、ジョン・フォン・ノイマンの言い回し「乱数ほど重要ではありません。

ランダムジェネレータのシードが異なることを保証できない場合(この場合は不可能と思われます)、別のシードを使用しないでください。 1つのシードジェネレータインスタンスを使用し、それから異なるシーケンスを取る。

+0

ありがとう、@タロン。それをするのは費用がかかりますか?例えば、各ループiはrng(i)を取る。 –

+0

違いはありません。変換呼び出しに異なるオフセットを渡しているだけです。 – talonmies

+0

もう一度ありがとうございます。私はそれをテストし、ellapseがほぼ同じ時間を見つける。 –

関連する問題