如果我正在使用Long uuid = UUID.randomUUID().getMostSignificantBits()它有可能发生碰撞.它切断了最不重要的位,所以你有可能遇到碰撞,对吗?
我打算为Linux编写一个C++ 11应用程序,它根据大约一百万个伪随机32位数进行一些数值模拟(不是加密).为了加快速度,我想使用桌面CPU的所有内核在并行线程中执行模拟.我想使用mt19937由boost提供的Mersenne Twister 作为PRNG,我想由于性能原因,每个线程我应该有一个这样的PRNG.现在我不确定如何播种它们以避免在多个线程中生成相同的随机数子序列.
以下是我到目前为止所考虑的替代方案:
独立于每个线程为PRNG播种/dev/urandom.
当系统熵池耗尽时,我有点担心,因为我不知道系统内部PRNG是如何运行的.我是否意外地获得连续的种子,这些种子准确地识别了Mersenne Twister的连续状态,因为/dev/urandom使用了Mersenne Twister本身?可能与我对下一点的担忧密切相关.
种第一个PRNG /dev/urandom和第一个PRNG .
基本上也是同样的问题:使用一个PRNG来播种另一个使用相同算法的PRNG是好还是坏?或者换句话说,在这一代中的任何时刻读取625个32位整数是否mt19937直接对应于mt19937发生器的内部状态?
首先从非梅森信息中获取其他人的种子.
由于使用相同的算法生成随机数并生成初始种子感觉某种方式可能是一个坏主意,我考虑引入一些不依赖于Mersenne Twister算法的元素.例如,我可以将线程id与初始种子向量的每个元素进行异或.这会让事情变得更好吗?
在线程中共享一个PRNG.
这将确保只有一个序列,具有Mersenne Twister的所有已知和期望的属性.但是控制对该生成器的访问所需的锁定开销确实让我有点担心.由于我没有发现任何相反的证据,我认为我作为图书馆用户将负责阻止对PRNG的并发访问.
预生成所有随机数.
这将有一个线程预先生成所有必需的1M随机数,稍后将由不同的线程使用.与整个应用程序相比,4M的内存要求会很小.在这种方法中最让我担心的是随机数本身的产生并不是并发的.整个方法也不能很好地扩展.
你会建议哪种方法,为什么?或者你有不同的建议吗?
你知道我的哪些问题是合理的,而这仅仅是因为我对事情的实际运作缺乏洞察力?