2

我在互联网上进行了很多搜索,以找到一种在内核中在我的 CUDA 设备上生成随机数的方法。这些数字必须来自高斯分布。

我发现最好的东西来自 NVIDIA 本身。这是华莱士算法,它使用均匀分布来构建高斯分布。但是他们给出的代码示例缺乏解释,我真的需要了解算法是如何进行的,尤其是在设备上。例如,他们给出:

 __device__ void generateRandomNumbers_wallace(  
unsigned seed,  // Initialization seed  
 float *chi2Corrections,  // Set of correction values  
 float *globalPool,  // Input random number pool  
 float *output  // Output random numbers  


    unsigned tid=threadIdx.x;  
    // Load global pool into shared memory.  
     unsigned offset = __mul24(POOL_SIZE, blockIdx.x);  
    for( int i = 0; i < 4; i++ )  
      pool[tid+THREADS*i] = globalPool[offset+TOTAL_THREADS*i+tid];  
    __syncthreads();  
      const unsigned lcg_a=241;  
      const unsigned lcg_c=59;  
      const unsigned lcg_m=256;  
      const unsigned mod_mask = lcg_m-1;  
      seed=(seed+tid)&mod_mask ;  
      // Loop generating outputs repeatedly  
     for( int loop = 0; loop < OUTPUTS_PER_RUN; loop++ )  
      {  
        Transform();  
        unsigned intermediate_address;  
        i_a = __mul24(loop,8*TOTAL_THREADS)+8*THREADS *  
          blockIdx.x + threadIdx.x;  
        float chi2CorrAndScale=chi2Corrections[  
          blockIdx.x * OUTPUTS_PER_RUN + loop];  
        for( i = 0; i < 4; i++ )  
          output[i_a + i*THREADS]=chi2CorrAndScale*pool[tid+THREADS*i];  
    }  

首先,许多声明的变量甚至没有在函数中使用!而且我真的不明白第二个循环中的“8”是什么意思。我知道其他循环中的“4”与 4x4 正交矩阵块有关,对吗?谁能让我更好地了解这里发生了什么?

无论如何,有人有我可以使用的好的代码示例吗?或者有人有另一种在 CUDA 内核中生成随机高斯数的方法吗?代码示例将不胜感激。

谢谢!

4

3 回答 3

4

您可以使用CURAND,它包含在 CUDA 工具包(版本 3.2 及更高版本)中。会简单很多!

关于您发布的代码的一些注释:

  • 华莱士生成器将高斯转换为高斯(即不均匀到高斯)
  • CUDA 代码有两个隐式变量:blockIdxthreadIdx- 这些变量定义了块索引和线程索引,有关更多信息,请参阅CUDA 编程指南
  • 该代码在 sm_20 上使用 __mul24,后来这实际上比“普通”32 位乘法要慢,所以我会避免它(为了简单起见,即使在旧架构上也是如此)
于 2011-01-22T18:40:28.293 回答
1

Box-Muller 方法也很好。

于 2011-01-20T05:34:21.180 回答
1

快速 Walsh Hadamard 变换是通过加法和减法的模式完成的。因此中心极限定理适用。经过 Walsh Hadamard 变换的均匀随机数数组将具有高斯/正态分布。对此有一些轻微的技术细节。该算法不是由华莱士发现的。它由我自己在 1993/1994 年左右首次在 Servo Magazine 上发表。我在 www.code.google.com/p/lemontree Regards 上有关于 Walsh Hadamard 变换的代码,Sean O'Connor

于 2012-06-19T05:47:28.277 回答