我正在使用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
都可以]编辑:
@@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> >
最重要的是,您真的需要100,000,000个随机数同时吗?所有这些数据的写入和随后从RAM的读取不可避免地需要大量时间。如果一次只需要一个随机数,则应避免这种情况。
假设您确实需要所有这些编号在RAM中,那么您应该首先如果您确实想知道CPU时间花在哪里/丢失了,则对代码进行概要分析。
第二,您应该避免不必要的数据重新分配和初始化。将std::vector::reserve(final_size)
与std::vector::push_back()
结合使用最容易做到这一点。
第三,您可以使用比std::mt19937
更快的RNG。当数字的质量很重要时,建议使用RNG。 online documentation表示lagged Fibonacci generator(在std:: subtract_with_carry_engine
中实现)速度很快,但是它可能没有足够长的重复周期-您必须检查一下。或者,您可能要使用std:: subtract_with_carry_engine
(使用std::min_stdrand
)
linear congruential generator
您还希望研究std :: vector保留而不是调整大小。它可以让您在1秒钟内获得所需的全部内存。我假设您不需要一次获得全部1亿个双打吗?
[如果确实是导致性能下降的生成器,则使用普通的std::vector<double> make_normal_random(std::size_t number,
std::uint_fast32_t seed)
{
std::normal_distribution<double> normalDistr(0,1);
std::min_stdrand generator(seed);
std::vector<double> randNums;
randNums.reserve(number);
while(number--)
randNums.push_back(normalDistr(generator));
return randNums;
}
函数(您需要成对绘制数字),转换为float或double in 0,1,然后应用Box Muller转换。
就时间而言,这很难克服,但请注意,统计属性并不比rand
好。
一个数字配方例行程序gasdev可以做到这一点-您应该可以下载一个副本。