GPU上的蒙特卡洛

时间:2011-04-05 18:28:57

标签: random gpu seed montecarlo

今天我与我的一位朋友进行了一次谈话,告诉我他试图用GPU进行一些蒙特卡罗模拟。有趣的是,他告诉我,他想在不同的处理器上随机抽取数字,并假设存在不相关的数字。但他们不是

问题是,是否存在在多个GPU上绘制独立数字集的方法?他认为为每个人拿一个不同种子可以解决问题,但事实并非如此。

如果需要澄清,请告诉我,我会请他提供更多详细信息。

3 个答案:

答案 0 :(得分:5)

要生成完全独立的随机数,您需要使用并行随机数生成器。实质上,您选择单个种子并生成 M 独立随机数流。因此,在每个 M GPU上,您可以从独立流中生成随机数。

处理多个GPU时,您需要注意:

  • GPU内的独立流(如果每个GPU生成RN)
  • GPU之间的独立流。

事实证明,在每个GPU内核上生成随机数很棘手(请参阅this question我问过一段时间)。当我一直在玩GPU和RN时,如果你一次生成大数字,你只能在GPU上随机生成加速。

相反,我会在CPU上生成随机数,因为:

  • 在CPU上生成它们并进行转移更容易,有时更快。
  • 您可以使用经过良好测试的并行random number generators
  • 适用于GPU的现成随机数生成器的类型非常有限。
  • 当前GPU随机数库仅从少量发行版生成RN。

在评论中回答您的问题:随机数取决于什么?

一个非常基本的随机数生成器是linear congruential generator。尽管这种发生器已被新方法所超越,但它应该让您了解它们的工作原理。基本上,第i个随机数取决于(i-1)随机数。正如您所指出的,如果您运行两个足够长的流,它们重叠。最大的问题是,你不知道什么时候会重叠。

答案 1 :(得分:3)

要生成 iid 统一变量,您只需使用不同的种子初始化您的生成器。使用Cuda,您可以使用实现Mersenne Twister发生器的NVIDIA Curand Library。

例如,以下代码由100个内核并行执行,将绘制10个样本(R ^ 10) - 均匀

__global__ void setup_kernel(curandState *state,int pseed)
{
    int id =  blockIdx.x * blockDim.x + threadIdx.x;
    int seed = id%10+pseed;

    /* 10 differents seed for uncorrelated rv, 
    a different sequence number,    no offset */
    curand_init(seed, id, 0, &state[id]);
}

答案 2 :(得分:0)

如果你采用任何“好”的发生器(例如Mersenne Twister等),那么具有不同随机种子的两个序列将是不相关的,无论是在GPU还是CPU上。因此,我不确定你的意思是说在不同的GPU上采用不同的种子是不够的。你会详细说明吗?

相关问题