C++ C++;快速正态随机数发生器

C++ C++;快速正态随机数发生器,c++,random,normal-distribution,C++,Random,Normal Distribution,我正在使用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); } 如果确实是生成器导致性能下降,

我正在使用
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);
}

如果确实是生成器导致性能下降,则使用普通的
rand
函数(需要成对绘制数字),将其转换为0中的浮点或双精度,然后应用Box-Muller变换

这在时间上很难击败,但请注意,统计特性并不比兰德好多少


gasdev的数字配方例程可以做到这一点-您应该能够下载副本。

您还需要查看std::vector reserve,而不是调整大小。它将允许您在一次拍摄中获得所需的所有内存。我想你不需要一次就把1亿个双打都用上

最重要的是,您真的需要同时使用100000000个随机数吗?所有这些数据的写入和随后从RAM读取不可避免地需要大量时间。如果你一次只需要一个随机数,你应该避免

假设您确实需要RAM中的所有这些数字,那么您应该首先 如果您真的想知道CPU时间在哪里花费/损失,请配置您的代码

其次,您应该避免不必要的数据重新分配和初始化。使用
std::vector::reserve(final\u size)
std::vector::push\u back()
可以很容易地做到这一点

第三,您可以使用比std::mt19937更快的RNG。当数字的质量非常重要时,建议使用RNG。表示(在中实现的)是快速的,但是它可能没有足够长的重复周期——您必须检查这一点。或者,您可能希望使用
std::min\stdrand
(使用)

std::vector使正常随机(std::size\t编号,
标准::uint_fast32_t seed)
{
标准:正态分布正态分布(0,1);
标准:最小标准和发生器(种子);
std::矢量随机数;
随机储备(数量);
while(数字--)
randNums.推回(正常分布(生成器));
返回随机数;
}

我不相信这是RNG。你分析过你的代码吗?@user207933我错了。它应该说:而不是使用
向量随机数(1000000)
您可以使用
矢量随机数;随机储备(1000000)。这将节省将所有元素设置为0的时间。也许您可以考虑不生成1亿个随机数。你为什么需要这么多?你在问一个关于优化的问题。请包括评测代码的结果。瓶颈很有可能不在你认为的地方。@所有认为高质量RNG并将其映射到正态分布的人都很便宜:根据我(昏昏欲睡)的计算,在gdb中单步执行时,每次数字生成循环迭代大约需要485条指令。(我想我数错了一两次)。其中许多是FP mul和add,它们有3个和5个周期的延迟(在Intel SnB上)。因此,生成一个随机数并将其映射到正态分布并不便宜。(顺便说一句,我认为很多成本来自正态分布,而不是MT PRNG)。
std::normal_distribution
已经做到了(Box-Muller变换)。不能推荐C++中的<代码> RAND()/<代码>。数字配方不是免费软件,但需要许可证。
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> >
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;
}