使用Mersenne Twister生成数字(CURAND函数)

时间:2014-04-15 13:22:52

标签: random cuda parallel-processing

我遇到了通过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

1 个答案:

答案 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不同,您不能为每个线程提供状态的本地副本,所有线程都协同工作在该状态。