如何保证随机数生成器种子每次推力都不同

时间:2016-12-12 04:33:15

标签: cuda thrust

当我们编写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运行几次时,我们如何为每个操作设置不同的种子? 我试着重写代码如下:

#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,..... 10000,10001,... N),但这样做会很昂贵吗?

1 个答案:

答案 0 :(得分:3)

用约翰·冯·诺伊曼的话来解释“没有什么比随机数更重要了”。

如果你不能保证随机发生器的种子不同(在这种情况下似乎你不能),那么不要尝试使用不同的种子。使用一个种子生成器实例并从中获取不同的序列。