【发布时间】:2016-02-21 15:29:21
【问题描述】:
我正在使用mt19937 生成器生成正常的随机数,如下所示:
normal_distribution<double> normalDistr(0, 1);
mt19937 generator(123);
vector<double> randNums(1000000);
for (size_t i = 0; i != 1000000; ++i)
{
randNums[i] = normalDistr(generator);
}
上面的代码可以工作,但是由于我在我的代码中生成了超过 1 亿个正常随机数,所以上面的代码非常慢。
有没有更快的方法来生成正常的随机数?
以下是有关如何使用代码的一些背景知识:
- 随机数的质量并不那么重要
- 数字的精度不是那么重要,
double或float都可以 - 正态分布的均值 = 0 和 sigma = 1
编辑:
@Dúthomhas,安德鲁:
分析后,以下函数占用了超过 50% 的时间:
std::normal_distribution<double>::_Eval<std::mersenne_twister_engine<unsigned int,32,624,397,31,2567483615,11,4294967295,7,2636928640,15,4022730752,18,1812433253> >
【问题讨论】:
-
我不相信这是 RNG。你分析过你的代码吗?
-
@user2079303 我错了。应该说:您可以使用
vector<double> randNums; randNums.reserve(1000000);,而不是使用vector<double> randNums(1000000);。这样可以节省将所有元素设置为 0 的时间。 -
也许您可以考虑不生成 1 亿个随机数。为什么需要这么多?
-
您在问一个关于优化的问题。请在您的代码中包含分析的结果。瓶颈很可能不在您认为的位置。
-
@everyone 认为高质量的 RNG 并将它们映射到正态分布很便宜:根据我在 gdb 中单步执行时的(昏昏欲睡的)计数,每次大约需要 485 条指令数字生成循环的迭代,when compiled with gcc 5.2
-O3 -ffast-math。 (我想我数不清一次或两次)。其中许多是 FP mul 和 add,它们具有 3 和 5 个周期的延迟(在 Intel SnB 上)。所以生成一个随机数并将其映射到正态分布是不便宜。 (顺便说一句,我认为 很多 成本来自正态分布,而不是 MT PRNG)。
标签: c++ random normal-distribution