我正在使用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,Andrew:
分析后,以下功能占用的时间超过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> >
答案 0 :(得分:3)
最重要的是,你真的需要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::min_stdrand
(使用linear congruential generator)
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;
}
答案 1 :(得分:2)
您还需要查看std :: vector reserve而不是调整大小。它将允许您获得1次拍摄所需的所有记忆。我假设你不需要一次全部1亿双打?
答案 2 :(得分:0)
如果确实是生成器导致性能下降,那么使用普通的rand函数(需要成对绘制数字),转换为浮点数或在0,1中加倍,然后应用Box Muller变换。
这在时间上很难被击败,但请注意统计属性并不比兰特好。
数字食谱例程gasdev这样做 - 您应该能够下载副本。