CUDA CURAND是否容易受到数据竞争的影响?

时间:2013-01-16 05:21:12

标签: random cuda gpgpu race-condition

我从Setup()内核生成 1个256线程块,以设置具有256个CURAND状态的数组RNGstates

__global__ void Setup(curandState *RNGstates, long seed) {
    int tid = threadIdx.x;
    curand_init(seed, tid, 0, &RNGstates[tid]);
}

现在,我从Generate()内核中生成 1000个256个线程的块,用256,000个随机数填充数组result。但是,我只使用RNGstates的256个状态,这样每个状态将被1000个线程访问(每个块一个):

__global__ void Generate(curandState *RNGstates, float *result) {
    int tid = blockIdx.x*blockDim.x + threadIdx.x;
    float rnd = curand_uniform(&RNGstates[threadIdx.x]);
    result[tid] = rnd;
}

我知道调用curand_uniform()会以某种方式更新状态,所以我假设正在进行一些写操作。

当映射到256个CURAND状态中的每一个的1000个线程尝试通过curand_uniform()隐式更新状态时,我应该担心会发生数据争用吗?这是否会影响我的随机数的质量(例如,获得频繁的重复值)?

非常感谢。

2 个答案:

答案 0 :(得分:3)

我认为分享国家肯定会影响质量。重复值是共享状态的最佳情况。数据竞争可能完全破坏各州。

你可以为每个线程保留一个状态。

使用1000个块时,您的案例需要256,000个状态。代码应该像

__global__ void Setup(curandState *RNGstates, long seed) {
  int tid = blockIdx.x*blockDim.x + threadIdx.x;
  curand_init(seed, tid, 0, &RNGstates[tid]);
}

__global__ void Generate(curandState *RNGstates, float *result) {
  int tid = blockIdx.x*blockDim.x + threadIdx.x;
  float rnd = curand_uniform(&RNGstates[tid]);
  result[tid] = rnd;
}

要减少多个块的内存要求,可以将#block限制为一个小数字,并为每个线程生成多个随机数,而不是每个线程1个随机数。

__global__ void generate_uniform_kernel(curandState *state, 
                                unsigned int *result)
{
    int id = threadIdx.x + blockIdx.x * 64;
    unsigned int count = 0;
    float x;
    /* Copy state to local memory for efficiency */
    curandState localState = state[id];
    /* Generate pseudo-random uniforms */
    for(int n = 0; n < 10000; n++) {
        x = curand_uniform(&localState);
        /* Check if > .5 */
        if(x > .5) {
            count++;
        }
    }
    /* Copy state back to global memory */
    state[id] = localState;
    /* Store results */
    result[id] += count;
}

有关如何处理多个块的完整示例,请参阅cuRAND参考手册中的Device API Examples部分。

答案 1 :(得分:2)

您也可以使用curandStateMtgp32_t,每个块只需要一个(如果每个块最多256个线程)http://docs.nvidia.com/cuda/curand/device-api-overview.html#bit-generation-1