Multithreading 与线程数无关的并行随机数序列

Multithreading 与线程数无关的并行随机数序列,multithreading,random,scientific-computing,deterministic,Multithreading,Random,Scientific Computing,Deterministic,这里有大量的并行RNG问题,但我找不到一个能解决我的变体的问题 我在写一个函数,给定一个种子,用基于该种子的随机数填充一个长数组。我目前是连续这样做的,但我发现RNG占用了我程序大量的运行时间。因此,我想通过使用多个线程来加速我的函数。但我希望这对用户是透明的。也就是说,给定一个种子,应该得到相同的随机数序列,与函数内部使用的线程数无关 我目前的想法是将数组划分为块(独立于线程数量),并为每个块生成一个新的RNG,例如,使用seed+chunk_id为每个RNG播种。然后可以独立处理这些块,而不

这里有大量的并行RNG问题,但我找不到一个能解决我的变体的问题

我在写一个函数,给定一个种子,用基于该种子的随机数填充一个长数组。我目前是连续这样做的,但我发现RNG占用了我程序大量的运行时间。因此,我想通过使用多个线程来加速我的函数。但我希望这对用户是透明的。也就是说,给定一个种子,应该得到相同的随机数序列,与函数内部使用的线程数无关

我目前的想法是将数组划分为块(独立于线程数量),并为每个块生成一个新的RNG,例如,使用seed+chunk_id为每个RNG播种。然后可以独立处理这些块,而不管哪个线程处理哪个块。但我担心这可能会降低RNG的质量。对于像mersenne捻线机这样的高质量RNG,这是一种安全的方法吗

为了说明这一点,下面是该过程的一些伪代码:

function random(array, seed, blocksize=100000)
  for each block of size blocksize in array
    rng[block] = create_rng(seed+i)
  parallel for each block in array
    for each sample in block
      array[sample] = call_rng(rng[block])

这将为每个(种子、块大小)组合生成相同的值。但这是最好的方法吗?

我通过构建一个自定义的RNG,每0x1000步用一个新的顺序种子重新播种,测试了该方法的有效RNG质量:

#include <stdlib.h>
#include "ulcg.h"
#include "unif01.h"
#include "bbattery.h"

long long i=1,j=0;
unif01_Gen * gen;

unsigned long myrand()
{
  if(++i&0xfff==0)
  {
    ugfsr_DeleteGen(gen);
    gen = ugfsr_CreateMT19937_02(++j, NULL, 0);
  }
  return gen->GetBits(gen->param, gen->state);
}

int main()
{
  unif01_Gen *gen2 = unif01_CreateExternGenBitsL("foo", myrand);
  gen = ugfsr_CreateMT19937_02(1, NULL, 0);
  bbattery_Crush (gen2);
  return 0;
}
这些都是相同的测试梅森捻线机失败,即使在正常使用时,不重新播种。因此TestU01挤压测试无法区分顺序播种场景和正常使用

我还测试了使用另一个Mersenne捻线器的输出重新播种的方法,而不是使用顺序整数。结果完全一样


虽然我没有尝试最耗时的“BigCrush”测试(需要8小时),但我认为可以肯定地说,如问题所述,使用顺序种子生成子RNG不会显著影响MT的质量。

我建议使用一个RNG来生成其他RNG的种子。您必须了解一点RNG的内部结构,以确保您的使用不会与其逻辑冲突。为什么这样会更好?数字1,2,3。。在RNG的状态空间中应该彼此远离,不是吗?这相当于说RNG不会因为替换为一种算法而被削弱,该算法使用连续整数对其进行种子排序,并且只从每个整数生成一个输出。我怀疑那是真的。(但如果你知道RNG拥有这个属性,那就去做吧。)不,我不是想说这个。我问这个问题是因为我担心这个问题。我想知道的是,为什么使用另一个RNG播种它们会更好。在一些简单的情况下,情况显然会更糟,例如对于只使用最后一个返回值作为其状态的简单rng。在这种情况下,每个子rng都会产生与其同级相同的序列,只是偏移量不同。我理解这就是为什么你说需要考虑RNG的内部,但这似乎是个问题。如果RNG是好的,那么它产生的输出序列将是好的和随机的。因此,它们将是好的种子——这就是你想要的。我不明白这个论点如何适用于相差一个的种子。(如果RNG有这样一个属性,即它的下一个输出可以通过它的前一个输出来确定,那么它就是一块垃圾(在本文中,这并不是说这些东西永远都是无用的)。)RNG需要一个随机种子是合理的。
      Test                          p-value
----------------------------------------------
71  LinearComp, r = 0              1 - eps1
72  LinearComp, r = 29             1 - eps1
----------------------------------------------
All other tests were passed