如何保证随机数生成器seed每次推力都不一样

How to guarantee the random number generator seed to be different each time in 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),但是这样做会很昂贵吗?

套用 John von Neumann "Nothing as important as random numbers should be left to chance"。

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