种子并行伪随机数生成器的好方法是什么?
What is a good way to seed parallel pseudo random number generators?
我写的PRNG的周期是2^64。当我使用自旋锁来保护它不受4个线程的影响时,它的运行速度比单线程时慢两倍。互斥锁似乎更能让事情变慢。所以我决定每个线程有单独的生成器,但这里的问题是,当种子太接近时,相同的随机数系列将一次又一次地出现在不同的线程中。我不能100%确定这对我的模拟有多糟糕,但我希望避免使用非常紧密的种子prng。
也许我最初的问题太不明确,无法得到一个简单的解决方案。下面我发布了我正在使用的PRNG。它在《虎胆龙威》或FIPS等统计测试中表现得非常好,但我真的无法证明为什么,因为我不是这方面的专家。我需要一种方法来找到4个或更多的发电机并行运行的好种子。对于两个种子,最差的一对种子是相同的种子,所以两个线程得到的是相同的随机数序列。最好的一对种子将产生两个没有重叠部分的序列。
我发现,随着并行生成器的数量或生成的随机数的数量或两者都增加,找到"最佳"种子集变得越来越困难。每个任务将至少有4个线程和至少10亿个随机数。
I我能达到的最简单的解决方案是周期性播种。有时我可能会得到一组不好的种子,但经过周期性的重新播种,它很快就会被更好的种子所取代。
我的问题是否有一个通用的解决方案,可以应用于任何PRNG?或者至少是我目前使用的发电机可用的东西?我可以改变我的PRNG,如果有一个是专门设计的,非常适合并行随机数生成。
static thread_local unsigned long long n;
void seedRand(unsigned long long s)
{
n = s;
}
unsigned genRand(void)
{
n *= 123456789;
n ^= n >> 3;
n ^= n << 5;
return n ^= n >> 7;
}
我可以改变我的PRNG,如果有一个是专门设计的,非常适合并行随机数生成
好吧,如果你愿意改变RNG,有一些生成器可以快速(跳过调用数的对数倍)跳过(又名跳蛙)。
它们在设计上保证不重叠。比如说,你的模拟每个线程需要10^9个RNG调用,可以在8个线程上运行,然后你从一个种子开始,第一个线程被跳过0,第二个线程被跳过10^9,线程号N被跳过(N-1)* 10^9。
合理可接受的一个(这是MCNP5 fortran代码的重新实现)在这里https://github.com/Iwan-Zotow/LCG-PLE63,但很可能不会通过龙胆。
更复杂的一个(我相信它通过了虎胆龙威)在这里http://www.pcg-random.org/
均基于快速幂,F. Brown的论文,"任意跨距的随机数生成",译。点。诊断。Soc。(1994年11月)
如果您可以访问加密库,那么您可以使用AES加密填充的初始种子,并在prng之间分割输出。例如,使用带有64位初始种子[seed]的计数器模式,您将将其连接直到得到256位的明文:
(种子)(种子)(种子)(种子)
和您的初始化向量将是[counter][seed](您需要一个唯一的初始化向量,但不一定是安全的初始化向量,因为没有人试图解密您的输出)。这将产生一个256位的输出,第一个64位种子第一个PRNG,第二个64位种子第二个PRNG,等等。
根据加密库中提供的内容,还有其他方法可以做到这一点,例如,您可以散列初始种子,或者您可以生成随机uuid,直到您有足够的位来播种所有prng。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 通过JNI传递数据数组的最快方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 在C++中包含原型文件的正确方法是什么?
- 在 OpenCV C++ 中估计基本矩阵之前对相应点进行归一化的正确方法是什么?
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 将一系列整数放入类的最佳方法是什么?
- 从长整整转换为uint64_t的推荐方法是什么?
- 将此布尔值传递给此函数的最有效方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?