【问题标题】:C++ computationaly efficient and threadsafe random functionC++ 计算效率高且线程安全的随机函数
【发布时间】:2011-11-22 20:18:55
【问题描述】:

我最近了解到the hard way #<cstdlib> rand() 不是线程安全的,并且在 Linux 上使用互斥锁实现,当多个线程频繁调用 rand() 时会导致瓶颈。 rand_r 作为替代品,但有 concerns 关于随机数生成的质量。此外,这种情况让我质疑是否有更快的随机数生成器,因为显然我的代码花费了大量时间来生成随机数。上面的链接中列出了一些替代方案,但我不确定它们的速度以及可能存在哪些其他替代方案。

【问题讨论】:

    标签: c++ multithreading random


    【解决方案1】:

    如果您不需要跨线程的任何统计控制,只需使用<random> 提供的工具:

    #include <random>
    
    typedef std:::mt19937 rng_type;
    std::uniform_int_distribution<rng_type::result_type> udist(0, 200);
    
    int main()  // this can be per thread!
    {
      rng_type rng;
    
      // seed rng first:
      rng_type::result_type const seedval = get_seed();
      rng.seed(seedval);
    
      rng_type::result_type random_number = udist(rng);
    
      return random_number;
    }
    

    Mersenne twister PRNG 既快速又具有良好的统计特性。在每个线程中维护一个单独的(和单独播种的)引擎对象可以避免所有并发问题。

    【讨论】:

    • @Kerrek &lt;random&gt; 使用梅森捻线机吗?它的速度与rand() 相比如何。另外这里如何获得新的随机数?我可以反复做= random_number,还是我必须每次都做random_number = udist(rng);
    • @MattMunson:std::mt19937 是一个特殊的梅森扭曲者。 rand() 不确定,但通常是线性同余 rng。 LC 速度很快,但 MT 具有更好的统计特性并且速度也很快。无论如何,请浏览 &lt;random&gt; 的文档,您可以选择多种引擎。它还将向您展示如何使用它们;通常最好通过我的例子中的分布(尽管如果你愿意,你也可以调用裸引擎)。
    • @Matt: 你也可以auto f = std::bind(udist, rng) 得到一个函数,每次你调用它时都会产生一个新的随机数,就像f()一样。
    【解决方案2】:

    在 Linux 中,您可以以非阻塞方式读取 /dev/urandom

    【讨论】:

    • 您永远不应该将系统的熵源用于大量的随机性。 urandom 非常适合播种,但不适用于持久随机数生成。据我所知,它甚至没有明确的分布。
    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多