【发布时间】:2021-02-12 09:05:14
【问题描述】:
我使用的是 64 位 LCG(MMIX(由 Knuth 制作))。它在我的代码中生成一定的随机数块,使用它们来执行一些操作。我的代码在单核中工作,我想并行化工作以减少执行时间。
在开始从这个意义上考虑更高级的方法之前,我想简单地并行执行更多相同的代码(事实上,代码在一定数量的独立模拟中重复相同的任务,所以我可以简单地将模拟数量拆分为更多相同的代码并并行运行)。
我现在唯一的问题是为每个代码找到一个种子;特别是,为了避免在不同代码中生成的数据之间出现不必要的非平凡相关性,我必须确保在各种代码中生成的随机数不会重叠。为此,从第一个代码中的某个种子开始,我必须找到一种方法来找到一个非常遥远的值(下一个种子),不是绝对值,而是伪随机序列(所以,这样,从第一到第二种子,我需要大量的LCG步骤)。
我的第一次尝试是这样的:
从序列中生成的2个连续数字之间的LCG关系开始
因此,原则上,我可以计算上述关系,例如,n = 2^40 和 I_0 等于第一个种子的值,并从第一个随机 CLG 序列中获得一个距离为 2^40 步的新种子.
问题是,这样做,我必须进行溢出计算 a^n。事实上,对于 MMIX(由 Knuth)a~2^62,我使用 unsigned long long int(64 位)。请注意,这里唯一的问题是上述关系中的分数。如果只有求和和乘法,由于以下模块化属性,我可以忽略溢出问题(实际上我使用 2^64 作为 c(64 位生成器)):
那么,从某个值(第一个种子)开始,如何在 LC 伪随机序列中找到第二个远离大量步长的值?
[编辑]
r3mainer 解决方案非常适合 python 代码。我现在正在尝试使用无符号的 __int128 变量在 c 中实现它。我只有一个问题:原则上我应该计算:
说,为简单起见,我想计算:
n = 2^40 和 c(a-1)~2^126。我继续循环。从temp = a 开始,在每次迭代中我计算temp = temp*temp,然后我计算temp%c(a-1)。问题出在第二步(temp = temp*temp)。 temp 实际上原则上可以是任何数字 temp 是一个很大的数字,比如 > 2^64,我会在下一个模块操作之前进入溢出,达到 2^128 - 1。那么有没有办法避免呢?目前我看到的唯一解决方案是使用循环位执行每个乘法,如下所示:c code: prevent overflow in modular operation with huge modules (modules near the overflow treshold)
在乘法过程中是否有另一种方法可以执行模运算?
(注意是c = 2^64,用mod(c)操作我没有同样的问题,因为溢出点(对于ull int变量)与模块重合)
【问题讨论】:
标签: random parallel-processing numbers overflow random-seed