# 在 GPU 上生成随机数

```d = gpuDevice; fprintf("This example is run on a " + d.Name + " GPU.")```
```This example is run on a GeForce GTX 1080 GPU. ```

### 探索 GPU 随机数生成器

`parallel.gpu.RandStream.list`
``` The following random number generator algorithms are available: MRG32K3A: Combined multiple recursive generator (supports parallel streams) Philox4x32_10: Philox 4x32 generator with 10 rounds (supports parallel streams) Threefry4x64_20: Threefry 4x64 generator with 20 rounds (supports parallel streams) ```

• CombRecursive（也称为 `MRG32k3a`）：该生成器于 1999 年推出，并已得到广泛的测试和使用。

• Philox（也称为 Philox4x32_10）：2011 年推出的新生成器，专为在 GPU 等高度并行系统中实现高性能而设计。

• Threefry（也称为 Threefry4x64_20）：2011 年推出的基于现有加密 ThreeFish 算法的新生成器，该算法经过了广泛的测试和使用。该生成器旨在在 GPU 等高度并行系统中提供良好的性能。这是 GPU 计算的默认生成器。

GPU 上可用的三个生成器也可用于 MATLAB® 中的 CPU。MATLAB 生成器具有相同的名称，并且在相同的初始状态下产生相同的结果。当您想在 GPU 和 CPU 上生成相同的随机数集时，这很有用。有关详细信息，请参阅GPU 上的随机数流

### 更改默认随机数生成器

```oldState = gpurng; gpurng(0, "Philox4x32-10"); disp(gpurng)```
``` Type: 'philox' Seed: 0 State: [7×1 uint32] ```

### 生成均匀分布的随机数

```generators = ["Philox","Threefry","CombRecursive"]; gputimesU = nan(100,3); for g=1:numel(generators) % Set the generator gpurng(0, generators{g}); % Perform calculation 100 times, timing the generator for rep=1:100 gputimesU(rep,g) = gputimeit(@() rand(10000,1000,"gpuArray")); end end```
```% Plot the results figure hold on histogram(gputimesU(:,1),"BinWidth",1e-4); histogram(gputimesU(:,2),"BinWidth",1e-4); histogram(gputimesU(:,3),"BinWidth",1e-4) legend(generators) xlabel("Time to generate 10^7 random numbers (sec)") ylabel("Frequency") title("Generating samples in U(0,1) using " + d.Name) hold off```

### 生成正态分布的随机数

```generators = ["Philox","Threefry","CombRecursive"]; gputimesN = nan(100,3); for g=1:numel(generators) % Set the generator gpurng(0, generators{g}); % Perform calculation 100 times, timing the generator for rep=1:100 gputimesN(rep,g) = gputimeit(@() randn(10000,1000,"gpuArray")); end end```
```% Plot the results figure hold on histogram(gputimesN(:,1),"BinWidth",1e-4); histogram(gputimesN(:,2),"BinWidth",1e-4) histogram(gputimesN(:,3),"BinWidth",1e-4) legend(generators) xlabel("Time to generate 10^7 random numbers (sec)") ylabel("Frequency") title("Generating samples in N(0,1) using " + d.Name) hold off```

`gpurng(oldState);`

### 结论

Threefry

• (`+`) 快

• (`+`) 基于著名且经过充分测试的 Threefish 算法

• `-`）在实际使用中相对较新

Philox

• (`+`) 快

• `-`）在实际使用中相对较新

CombRecursive

• (`+`) 在实际使用中有着长期的记录

• (`-`) 最慢

### 参考

[1] L'Ecuyer, P., and R. Simard."TestU01:A C library for empirical testing of random number generators."ACM Transactions on Mathematical Software.Vol. 33, No. 4, 2007, article 22.