利用C ++ 11< random>进行有效的随机数生成. [英] Efficient random number generation with C++11 <random>

查看:58
本文介绍了利用C ++ 11< random>进行有效的随机数生成.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解如何使用C ++ 11随机数生成功能.我关心的是性能.

I am trying to understand how the C++11 random number generation features are meant to be used. My concern is performance.

假设我们需要在 0..k 之间生成一系列随机整数,但是 k 每一步都会改变.最好的进行方法是什么?

Suppose that we need to generate a series of random integers between 0..k, but k changes at every step. What is the best way to proceed?

示例:

for (int i=0; i < n; ++i) {
    int k = i; // of course this is more complicated in practice
    std::uniform_int_distribution<> dist(0, k);
    int random_number = dist(engine);
    // do something with random number
}

< random> 标头提供的分布非常方便.但是它们对用户而言是不透明的,因此我无法轻松预测它们的性能.例如,尚不清楚上述 dist 的构造会导致多少(如果有)运行时开销.

The distributions that the <random> header provides are very convenient. But they are opaque to the user, so I cannot easily predict how they will perform. It is not clear for example how much (if any) runtime overhead will be caused by the construction of dist above.

相反,我本可以使用类似的东西

Instead I could have used something like

std::uniform_real_distribution<> dist(0.0, 1.0);
for (int i=0; i < n; ++i) {
    int k = i; // of course this is more complicated in practice
    int random_number = std::floor( (k+1)*dist(engine) );
    // do something with random number
}

避免在每次迭代中构造新对象.

which avoids constructing a new object in each iteration.

随机数通常用于对性能很重要的数值模拟中.在这些情况下使用< random> 的最佳方法是什么?

Random numbers are often used in numerical simulations where performance is important. What is the best way to use <random> in these situations?

请不要回答配置文件".分析是有效优化的一部分,但对如何使用库以及该库的性能特征也有很好的了解.如果答案是它取决于标准库的实现,还是知道它的唯一方法就是对其进行概要分析,那么我宁愿完全不使用< random> 中的发行版.相反,我可以使用自己的实现方式,该实现方式对我来说是透明的,并且在需要时/更容易进行优化.

Please do no answer "profile it". Profiling is part of effective optimization, but so is a good understanding of how a library is meant to be used and the performance characteristics of that library. If the answer is that it depends on the standard library implementation, or that the only way to know is to profile it, then I would rather not use the distributions from <random> at all. Instead I can use my own implementation which will be transparent to me and much easier to optimize if/when necessary.

推荐答案

您可以做的一件事是拥有一个永久的 distribution 对象,以便仅创建 param_type 每次这样的对象:

One thing you can do is to have a permanent distribution object so that you only create the param_type object each time like this:

template<typename Integral>
Integral randint(Integral min, Integral max)
{
    using param_type =
        typename std::uniform_int_distribution<Integral>::param_type;

    // only create these once (per thread)
    thread_local static std::mt19937 eng {std::random_device{}()};
    thread_local static std::uniform_int_distribution<Integral> dist;

    // presumably a param_type is cheaper than a uniform_int_distribution
    return dist(eng, param_type{min, max});
}

这篇关于利用C ++ 11&lt; random&gt;进行有效的随机数生成.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆