【问题标题】:Would non thread safety increase the randomness of a Multiply-with-Carry pseudo-random number generator?非线程安全性会增加乘以进位伪随机数生成器的随机性吗?
【发布时间】:2012-08-19 11:06:07
【问题描述】:

我正在阅读this section,最后一段指出示例代码不是线程安全的。我的问题是:这是否有助于增加它的随机性(即如果多个线程要同时执行这些行)?

【问题讨论】:

  • 你听说过比赛条件这个词吗?
  • 是的,我有;但这就是重点。竞争条件不是随机活动的潜在来源吗?这不能给代码增加另一层随机性吗?
  • PNRG 可能被设计成具有良好的输出属性。这并不一定意味着它的中间计算状态是随机的,如果你有竞争条件,这就是你的读数。
  • 也不能保证您的比赛条件是随机的。您可以轻松地拥有定期重现完全相同的竞争条件的时间依赖性。

标签: c algorithm random


【解决方案1】:

PRNG 是经过精心设计的(好吧,也许不是 RANDU),以产生可预测且足够随机分布的结果。它们不必是真正随机的,它们只需要满足统计质量测试、产生足够大的周期并且对相同的种子具有确定性。

如果您碰巧同时从多个线程使用生成器,那么所有这些保证都会付诸东流。最重要的是,您无法获得可重现的结果(这在模拟中极为重要)。然后状态可能会发生变化,或者您可能会在不同的线程中两次获得相同的数字,这些事情。

你肯定不想去那里。每个线程创建一个 PRNG(最好使用线性独立的种子)。

【讨论】:

  • 所以如果我制作一个非线程安全的 PRNG(并且它不会破坏内部状态,正如 Sean 所提到的),我可以获得一个“几乎”的 RNG 吗?
  • 没有理由尝试这样做。一方面,线程不安全是非常不可预测的,因此您无法依赖可能发生的事情。其次,PRNG 通常有非常具体的用途,而这些用途需要他们对序列做出的保证。
  • @someDude 比赛条件不是位扰码器。最可能的结果是一些中间值将继续被重用。它发生的模式将是不可预测的,所以那里有一个随机元素。但是那个古老的“九九九九”Dilbert cartoon仍然浮现在脑海中。
【解决方案2】:

非线程安全随机数生成器的一个可能副作用是您可能会以某种方式破坏内部状态。例如,如果您从两个不同的线程访问 .NET 的 Random 的同一个实例,则可以将其置于不断重复返回 0 的状态。

在您链接的 RNG 中,看起来不会发生特定问题,但某些退化的并发访问模式可能会将 m_zm_w 设置为 0,根据 cmets 也将是不好。

【讨论】:

  • 顺便说一句,有a simple way 使用.Net Random 类来构建线程安全版本。
【解决方案3】:

您绝对可以从线程计时生成中获得熵,但是将熵收集和伪随机数生成混合在一起是一个非常糟糕的主意,因为前者可能会干扰后者的其他可证明的属性 - 就像 Joey 所做的那样说。我添加新答案的原因是您可能会考虑将真实熵与您的 PRNG 混合(作为种子,或定期引入更多),并从不同线程收集真实时间信息是熵的一种可能来源。然而,它应该严格执行(使用适当的锁定或无锁原子操作来存储结果),而不是通过调用未定义的行为并希望得到熵。

【讨论】:

    【解决方案4】:

    代码非线程安全的方式有很多种。

    一种方法是线程无法看到其他线程对内存的写入。

    我们可能会发现生成全零的随机数,因为它永远不会“看到”其他线程所做的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-08
      相关资源
      最近更新 更多