C ++快速普通随机数生成器

问题描述 投票:3回答:3

我正在使用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亿个普通随机数,因此上面的代码非常慢。

是否有更快的方法来生成普通随机数?

以下是有关如何使用代码的一些背景知识:

  • 随机数的质量不是那么重要
  • 数字的精度不是那么重要,doublefloat都可以]
  • 正态分布始终具有均值= 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,1812433‌​253> >
c++ random normal-distribution
3个回答
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:: subtract_with_carry_engine(使用std::min_stdrand

linear congruential generator

2
投票

您还希望研究std :: vector保留而不是调整大小。它可以让您在1秒钟内获得所需的全部内存。我假设您不需要一次获得全部1亿个双打吗?


0
投票

[如果确实是导致性能下降的生成器,则使用普通的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可以做到这一点-您应该可以下载一个副本。

© www.soinside.com 2019 - 2024. All rights reserved.