随机数,C ++ 11 vs Boost [英] Random numbers, C++11 vs Boost

查看:112
本文介绍了随机数,C ++ 11 vs Boost的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在C ++中生成伪随机数,这两个可能的选项是C ++ 11和Boost对应项的功能.它们的使用方式基本上相同,但是在我的测试中,原生速度大约慢了4倍.

I want to generate pseudo-random numbers in C++, and the two likely options are the feature of C++11 and the Boost counterpart. They are used in essentially the same way, but the native one in my tests is roughly 4 times slower.

是由于库中的设计选择,还是我缺少某种在某处禁用调试代码的方式?

Is that due to design choices in the library, or am I missing some way of disabling debug code somewhere?

更新:代码在此处, https ://github.com/vbeffara/Simulations/blob/master/tests/test_prng.cpp 看起来像这样:

Update: Code is here, https://github.com/vbeffara/Simulations/blob/master/tests/test_prng.cpp and looks like this:

cerr << "boost::bernoulli_distribution ...      \ttime = ";
s=0; t=time();
boost::bernoulli_distribution<> dist(.5);
boost::mt19937 boostengine;
for (int i=0; i<n; ++i) s += dist(boostengine);
cerr << time()-t << ",  \tsum = " << s << endl;

cerr << "C++11 style ...                        \ttime = ";
s=0; t=time();
std::bernoulli_distribution dist2(.5);
std::mt19937_64 engine;
for (int i=0; i<n; ++i) s += dist2(engine);
cerr << time()-t << ",  \tsum = " << s << endl;

(使用std::mt19937而不是std::mt19937_64会使它在我的系统上更慢.)

(Using std::mt19937 instead of std::mt19937_64 makes it even slower on my system.)

推荐答案

很漂亮可怕的.

让我们看看:

boost :: bernoulli_distribution<>

boost::bernoulli_distribution<>

if(_p == RealType(0))
    return false;
else
    return RealType(eng()-(eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());

std :: bernoulli_distribution

std::bernoulli_distribution

__detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng);
if ((__aurng() - __aurng.min()) < __p.p() * (__aurng.max() - __aurng.min()))
    return true;
return false;

两个版本都调用引擎,并检查输出是否在与给定概率成比例的值范围内.

Both versions invoke the engine and check if the output lies in a portion of the range of values proportional to the given probability.

最大的区别在于,gcc版本调用了助手类_Adaptor的函数.

The big difference is, that the gcc version calls the functions of a helper class _Adaptor.

此类的minmax函数分别返回01,然后operator()然后使用给定的URNG调用std::generate_canonical以获取介于01之间的值.

This class’ min and max functions return 0 and 1 respectively and operator() then calls std::generate_canonical with the given URNG to obtain a value between 0 and 1.

std::generate_canonical是带有循环的20行函数–在这种情况下,它永远不会重复多次,但会增加复杂性.

std::generate_canonical is a 20 line function with a loop – which will never iteratate more than once in this case, but it adds complexity.

除此之外,boost仅在发行版的构造函数中使用param_type,然后将_p保存为double成员,而gcc具有param_type成员,并且必须获取"值它的.

Apart from that, boost uses the param_type only in the constructor of the distribution, but then saves _p as a double member, whereas gcc has a param_type member and has to "get" the value of it.

这一切融合在一起,编译器无法进行优化. 铛声在它上面窒息了更多.

This all comes together and the compiler fails in optimizing. Clang chokes even more on it.

如果您锤子足够硬,您甚至可以获得std::mt19937boost::mt19937 en等于gcc.

If you hammer hard enough you can even get std::mt19937 and boost::mt19937 en par for gcc.

也可以测试libc ++,也许以后再补充.

It would be nice to test libc++ too, maybe i’ll add that later.

经过测试的版本:boost 1.55.0,gcc 4.8.2的libstdc ++标头
根据要求提供行号^^

tested versions: boost 1.55.0, libstdc++ headers of gcc 4.8.2
line numbers on request^^

这篇关于随机数,C ++ 11 vs Boost的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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