我遇到了通过MTGP32生成器生成号码的问题。我已经使用过XORWOW或MG32k3a,所以我也一样。当我进入内核时,我将状态复制到局部变量中,然后我处理它。在这里,我尝试做同样的事情,但生成器保持给出相同的随机数,而当我使用指针时,它一切正常。这是包含副本的代码:
__global__ void generate_kernel( curandStateMtgp32 *state,
int n )
{
int id = threadIdx.x + blockIdx.x * blockDim.x;
float x;
curandStateMtgp32 localState = state[blockIdx.x];
/* Generate pseudo-random normal variable */
for(int i = 0; i < n; i++) {
x = curand_normal( &localState );
printf("tid: %d x: %f\n", id, x);
}
}
这是输出(tid 1&amp; 2每次得到相同的结果):
tid: 0 x: 0.207837
tid: 1 x: -0.091346
tid: 2 x: 0.294019
tid: 0 x: 2.684819
tid: 1 x: -0.091346
tid: 2 x: 0.294019
tid: 0 x: 1.433268
tid: 1 x: -0.091346
tid: 2 x: 0.294019
当我使用指针时,结果是正确的。这是代码:
__global__ void generate_kernel( curandStateMtgp32 *state,
int n )
{
int id = threadIdx.x + blockIdx.x * blockDim.x;
float x;
curandStateMtgp32 * localState = &state[blockIdx.x];
/* Generate pseudo-random normal variable */
for(int i = 0; i < n; i++) {
x = curand_normal( localState );
printf("tid: %d x: %f\n", id, x);
}
}
结果是:
tid: 0 x: 0.207837
tid: 1 x: -0.091346
tid: 2 x: 0.294019
tid: 0 x: 2.684819
tid: 1 x: -1.183960
tid: 2 x: -0.621348
tid: 0 x: 1.433268
tid: 1 x: 0.571323
tid: 2 x: -0.735758
有人可以解释一下我做错了什么,或者它是否是编译器的错误?我不明白为什么当我使用州的副本时,第一个帖子有不同的号码,而其他人不在。
谢谢。
如果您想自己测试,我可以发布整个代码。
我正在使用RED HAT 6.x - GPU K20xm - CUDA 5.5
编译行:nvcc -arch=sm_35 -lcurand x.cu
答案 0 :(得分:3)
阅读here内核Mersenne twister生成的工作原理。特别是,“MTGP32序列的一个完整状态由351个32位整数定义。每个线程T(m)对这些整数之一进行操作,s(n + m)将其与s(n + m + 1)组合并且拾取元素s(n + m + p),其中p <= 95.它将新状态存储在状态数组中的位置s(n + m + 351)。在线程同步之后,基本索引n被提前通过已更新状态的线程数。“与XORWOW不同,您不能为每个线程提供状态的本地副本,所有线程都协同工作在该状态。