我使用随机数编写了大量的物理模拟代码,我只是第一次分析了我的代码,所以我可能在读取输出时出错,但我看到下面这一行出现在前面:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
90.09 21.88 21.88 265536 0.08 0.08 std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>::operator()()这似乎意味着生成数字生成器需要90%的时间。我之前已经写了一篇文章,询问不在每个循环中构造随机概率分布是否可以节省我的时间,但在尝试和计时之后,它没有帮助(Is defining a probability distribution costly? )。有没有优化随机数生成的常用选项?
提前谢谢你,我的模拟(在当前状态下)运行了几天,所以减少90%的计算时间将是一个重大的进步。
发布于 2013-11-20 19:43:23
总是在效率,即速度和大小(状态的字节数)和任何RNG的“随机性”之间进行权衡。Mersenne twister具有相当好的随机性(假设您使用高熵种子,如std::random_device提供的),但速度较慢且状态较大。std::minstd_rand或std::knuth_b (线性同余)更快,ranlux48 (斐波那契)更快,但随机性更小(通过更少的随机性测试,即具有一些非随机谱特性)。只要试验和测试你是否对提供的随机性感到满意(即在随机数据中没有意外的相关性)。
编辑: RNG 1所有这些RNG都不是真正的随机,当然,对于密码学来说也不够随机。如果需要,可以使用std::random_device,但不要抱怨速度问题。并行使用2 (您应该考虑这样做),使用thread_local RNG,每个RNG都使用另一个种子进行初始化。
发布于 2013-11-20 20:07:08
如果您的代码将大部分时间花在生成随机数上,那么您可能希望花一些时间为您的应用程序选择最佳算法,然后自己实现它。Mersenne Twister是一个非常快的算法,具有很好的随机性,但你总是可以牺牲生成的随机数的一些质量来提高速度。这将取决于您的模拟需要什么,以及您正在生成的数字的类型(整型或浮点型)。如果你绝对需要良好的随机性,Mersenne Twister可能已经是你最好的选择之一。否则,您可能希望在代码中实现一个简单的linear congruential generator。
另一件要注意的事情是,如果你的代码是并行的,你应该使用随机数生成器的可重入版本,并确保不同的线程为它们的生成器使用自己的内部状态变量。否则,避免重写生成器的内部状态变量的互斥将大大减慢您的代码。请注意,许多库生成器不是可重入的。如果您的代码不是并行的,那么您可能应该将其并行化,并使用单独的线程来填充随机数列表,以供您的模拟使用。另一种选择是使用GPU并行生成随机数。
以下是比较不同生成器性能的一些链接:http://www.boost.org/doc/libs/1_38_0/libs/random/random-performance.html https://www.gnu.org/software/gsl/manual/html_node/Random-Number-Generator-Performance.html
发布于 2013-11-20 19:32:06
使用专用的随机数库。
我建议使用WELL512 (链接包含论文和源代码)。
https://stackoverflow.com/questions/20094599
复制相似问题