5

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

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

如果需要任何澄清,请告诉我,我会要求他提供更多细节。

4

3 回答 3

5

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

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

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

事实证明,在每个 GPU 内核上生成随机数是很棘手的(请参阅我不久前提出的这个问题)。当我一直在玩 GPU 和 RN 时,如果你一次生成大量数字,你只会在 GPU 上生成随机数得到加速。

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

  • 在 CPU 上生成它们并进行传输更容易,有时更快。
  • 您可以使用经过良好测试的并行随机数生成器
  • 可用于 GPU 的现成随机数生成器的类型非常有限。
  • 当前的 GPU 随机数库仅从少量分布中生成 RN。

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

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

于 2011-04-05T23:01:52.683 回答
3

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

例如,以下由 100 个内核并行执行的代码,将绘制 (R^10)-uniform 的 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]);
}
于 2011-06-17T12:50:26.110 回答
0

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

于 2011-04-07T14:44:15.483 回答