# 正态分布随机数生成器 **Repository Path**: ecui/Normal-Distribution-Random-Number-Generator ## Basic Information - **Project Name**: 正态分布随机数生成器 - **Description**: 快速、轻量级的正态随机数发生器,基于Box-Muller方法,包含SSE、AVX2加速版本。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: https://github.com/ErnestThePoet/Normal-Distribution-Random-Number-Generator - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-11-21 - **Last Updated**: 2022-05-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 正态分布随机数生成器 ### 介绍 快速、轻量级的单精度正态随机数发生器,基于Box-Muller方法实现,包含SSE、AVX2加速版本。 ### 质量与性能 底层实现了一个简单的线性同余发生器获取均匀分布浮点数。 发生器在显著度取0.01时通过了Kolmogorov-Smirnov检验,检验中`max{abs(Fobs(xi)-Fexp(xi))}`与numpy库差别极小。生成随机数足够多时,无优化版`Floats`函数略慢于numpy,耗时约为numpy的1.45倍;使用SSE加速时,随机数生成速度已经达到numpy的3倍;使用AVX+AVX2加速时,随机数生成速度可达numpy的7倍。注:numpy生成`np.float64`,故上述比较并不公平;*** **本正态随机数发生器只适合于希望高速获取正态随机数而不要求双精度的场合。** *** ### DLL导出函数列表 ``` void CreateGenerator(float mu, float sigma_square); float NextFloat(); float* Floats(unsigned int count); float* FloatsSSE(unsigned int count); float* FloatsAVX2(unsigned int count); ``` ### 使用方法 载入DLL后,首先调用 `CreateGenerator(float mu, float sigma_square)`来创建一个正态随机数发生器,同时给出正态分布的参数。 然后,根据具体需要,选择调用下列函数来获取正态随机数: - `NextFloat()` :获取下一个单精度正态随机数。如果之前没有调用过`CreateGenerator`函数,则返回`NaN`。 - `Floats(unsigned int count)` 生成`count`个单精度正态随机数置于数组中,返回指向数组第一个元素的`float`指针。如果之前没有调用过`CreateGenerator`函数,则返回`nullptr`(下面两个函数同)。 - `FloatsSSE(unsigned int count)` 使用SSE指令集加速的`Floats`函数,可期望约4倍的速度提升。 **注意:CPU必须支持SSE, SSE2, SSE4.1指令集,否则程序将崩溃。** - `FloatsAVX2(unsigned int count)` 使用AVX+AVX2指令集加速的`Floats`函数,可期望约8倍的速度提升。 **注意:CPU必须支持AVX和AVX2指令集,否则程序将崩溃。** ### 测试分析截图 1) K-S检验中Fexp与Fobs对比图像(μ=-3,σ²=9,生成100000个): ![输入图片说明](fig1.png) 2) 本发生器生成的正态随机数分布直方图,与numpy对比(μ=10,σ²=20,生成100000个): ![输入图片说明](fig2.png) 3) 生成随机数耗时比较(生成10000000个,i7-8565U): ![输入图片说明](fig3.png) # Happy Coding!