Where is it better to store random_device/mt19937?

huangapple go评论64阅读模式
英文:

Where is it better to store random_device/mt19937?

问题

我有一个使用随机性的函数

void fun() {
    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<double> dis(0.0, 1.0);
    // ...
}

而且,正如我怀疑的那样,如果反复调用它,并且每次都创建rdgen,那么我将获得较差的随机性。将这些变量作为类的全局/私有字段是否更好,以便它们不会被多次重新声明?

英文:

I have a function which makes use of randomness

void fun() {
    random_device rd;
	mt19937 gen(rd());
	uniform_real_distribution&lt;double&gt; dis(0.0, 1.0);
    // ...
}

And, as I suspect, I'll get poor random if it's call repeatedly and both rd and gen are created each time. Is it better to make these variables global/private fields of a class so they are not redeclared multiple times?

答案1

得分: 1

你可以使用 random_device 生成一个种子来初始化 mt19937。由于 random_device 是一个昂贵的操作,所以不需要每次调用函数时都调用它,也无需保存 random_device

mt19937 不是线程安全的。如果你的应用程序是单线程的,你可以将它保存为类的私有数据成员。然而,如果你的应用程序在多个线程中运行,最好将它设置为方法的线程局部变量。

void func() {
  thread_local mt19937(random_device{}());
}
英文:

You can use random_device to generate a seed to initialize mt19937. Since random_device is an expensive operation, no need to call it every time the function is called, and there's no need to save random_device.

mt19937 is not thread safe. If your application is single-threaded, you can save it as a private data member of your class. However, if your application runs in multiple-thread, you'd better make it a thread local variable of the method.

void func() {
  thread_local mt19937(random_device{}());
}

答案2

得分: 0

A random number generator should be a global object. But there is nothing wrong with burying it in a function for access:

template &lt;typename RealType&gt;
RealType random_real_in_range( RealType min = 0., RealType max = 1. )
{
  thread_local std::mt19937 rng( std::random_device{}() );
  return std::uniform_real_distribution&lt;RealType&gt;( min, max )( rng );
}

The drawback here is that MT really should be “warmed up” by calling .discard( 1000 ) or so...

英文:

A random number generator should be a global object. But there is nothing wrong with burying it in a function for access:

template &lt;typename RealType&gt;
RealType random_real_in_range( RealType min = 0., RealType max = 1. )
{
  thread_local std::mt19937 rng( std::random_device{}() );
  return std::uniform_real_distribution&lt;RealType&gt;( min, max )( rng );
}

The drawback here is that MT really should be “warmed up” by calling .discard( 1000 ) or so...

huangapple
  • 本文由 发表于 2023年2月16日 13:16:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75468104.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定