1

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

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

现在,我从内核中生成1000 个 256 个线程的块,用 256,000 个随机数Generate()填充数组。result但是,我只使用 256 个状态RNGstates,这样每个状态将被 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()?这会影响我的随机数的质量(例如获得频繁的重复值)吗?

非常感谢。

4

2 回答 2

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 参考手册中的设备 API 示例部分。

于 2013-01-16T07:03:18.073 回答
2

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

于 2013-08-22T11:28:10.633 回答