我为正态分布随机数生成基准创建了一个C ++开源项目。
它比较了几种算法,包括中心极限定理方法
Box-Muller变换
Marsaglia极地方法
Ziggurat算法
逆变换采样方法。
cpp11random使用C ++ 11 std::normal_distribution与std::minstd_rand(它实际上是箱穆勒变换在铛)。
floatiMac Corei5-3330S@2.70GHz上的单精度()版本的结果,clang 6.1,64位:
为了正确,程序验证样品的平均值,标准偏差,偏度和峰度。结果发现,通过求和4,8或16个均匀数的CLT方法与其他方法一样没有良好的峰度。
Ziggurat算法比其他算法具有更好的性能。但是,它不适合SIMD并行,因为它需要表查找和分支。具有SSE2 / AVX指令集的Box-Muller比非SIMD版本的ziggurat算法快得多(x1.79,x2.99)。
因此,我建议使用Box-Muller作为具有SIMD指令集的体系结构,否则可能是ziggurat。
PS基准测试使用最简单的LCG PRNG来生成均匀分布的随机数。因此对某些应用程序来说可能还不够。但性能比较应该是公平的,因为所有实现都使用相同的PRNG,因此基准测试主要测试转换的性能。