2014-05-01 48 views
-1

多个准随机数我想产生一个非常大的一套准随机数字。 (通过“非常大”,我指的并发线程的最大数目的任何电流CUDA设备可以支持, 要求每个线程循环,或与大格尺寸启动内核大得多。而且我想对于准随机他们的低差异性)。对于伪随机,每个curand_init的调用可以采用不同的序列参数this seems simpleCURAND - 生成每个线程

对于生成N个准随机数,其中N是大于gridDim.x * blockDim.x更大,是有一个解决方案比任

  1. 运行curand_init N次N个状态更有效的,给每个呼叫独特在[0偏移,N);
  2. 运行curand_initgridDim.x * blockDim.x次该数量的状态,但给每个调用例如一个偏移10*threadID,如果我期望每个线程必须生成10个数字?

(忽略任何开销,由于大的偏移,即忽略skip_ahead()。)


我看看CUDA 6.0样本代码,并MC_EstimatePiInlineQ 出现做什么,我是寻找两个维度。然而,当点产生的数量超过gridDim.x * blockDim.x,我相信这段代码实际上产生相同的点多次。这是一个问题,因为gridDim.x未必足够大以适应此示例中的问题大小;它被调整为针对设备上的每个多处理器大约10个块。

相关的代码是下面(略微改变为简洁起见):

// RNG init kernel 
template <typename rngState_t, typename rngDirectionVectors_t> 
__global__ void initRNG(rngState_t *const rngStates, 
         rngDirectionVectors_t *const rngDirections) 
{ 
    // Determine thread ID 
    unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x; 
    unsigned int step = gridDim.x * blockDim.x; 

    // Initialise the RNG 
    curand_init(rngDirections[0], tid, &rngStates[tid]); 
    curand_init(rngDirections[1], tid, &rngStates[tid + step]); 
} 

和,

// Estimator kernel 
template <typename Real, typename rngState_t> 
__global__ void computeValue(unsigned int *const results, 
          rngState_t *const rngStates, 
          const unsigned int numSims) 
{ 
    // Determine thread ID 
    unsigned int bid = blockIdx.x; 
    unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x; 
    unsigned int step = gridDim.x * blockDim.x; 

    // Initialise the RNG 
    rngState_t localState1 = rngStates[tid]; 
    rngState_t localState2 = rngStates[tid + step]; 

    // Count the number of points which lie inside the unit quarter-circle 
    unsigned int pointsInside = 0; 

    for (unsigned int i = tid ; i < numSims ; i += step) 
    { 
     Real x = curand_uniform(&localState1); 
     Real y = curand_uniform(&localState2); 

     // Do something. 
    } 

    // Do some more. 
} 

假设gridDim.x * blockDim.x < N,然后在for至少螺纹tid = 0将循环两次。在第二次运行中,它将生成相对于其初始化偏移0的第二个随机数;这相当于第一相对的随机数初始化偏移1,而这正是tid = 1做了第一时间。所以这个点已经产生了!除了最高的tid(即gridDim.x * blockDim.x的一些倍数)之外的所有线程都适用,如果它甚至多次循环。充其量这是无用的工作,对我的使用情况来说它是有害的。

我已经创建了上述示例的stripped-down version,它基于一些假设的设备,其中每块只有4个线程,只有2个块,但希望生成16个点。请注意,输出的第9-15行与第2-8行相同。只有第16行是一个新点。

+0

大概你的意思是'curand_init'而不是'cuda_init'在介绍中? – talonmies

+0

哦,是的。固定。 – Sam

回答

0

这只是阅读the docs的情况下,但在实践中,我发现它确实可以基本上更快地限制你生成状态的数量。

这相当于在问题选项2:每个线程的offsetcurand_init应该n * tid其中n至少如你所愿每个线程产生随机数的数量很大。如果在州代不知道,你可以改用skip_ahead(n * tid, &state),然后调用curandcurand_uniform等。