当我们编写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),但这样做会很昂贵吗?
答案 0 :(得分:3)
用约翰·冯·诺伊曼的话来解释“没有什么比随机数更重要了”。
如果你不能保证随机发生器的种子不同(在这种情况下似乎你不能),那么不要尝试使用不同的种子。使用一个种子生成器实例并从中获取不同的序列。