使用32位Mersenne Twister生成64位值

6
根据这个Boost文档页面,Mersenne Twister的64位变体比32位变体慢得多(这很有道理)。据我所知,C++11引入的许多功能,包括随机数生成,基本上都是标准库中的Boost。这让我相信,在标准C++中,32位MT的性能也更好。
我正在编写一个光线追踪器(主要是为了好玩),速度是我的主要关注点之一。基本上所有数值都表示为双精度浮点数。我的问题是,由于32位MT明显更快,我可以用它来生成双精度浮点数吗?我会遇到哪些缺点(精度损失,性能等)?

在随机数的背景下,“精度损失”是什么意思? - Oliver Charlesworth
@KerrekSB 有趣的观点。你能引用一下来源吗? - More Axes
@KerrekSB 哦,抱歉。我有点昏昏欲睡。有什么地方可以访问它吗?我只能找到付费来源,我想这种东西应该是公开可访问的。 - More Axes
@MoreAxes:可能已经添加了一个新的部分,而我还没有重新构建...无论如何,所讨论的部分描述了统计行为,这意味着必须收集足够的熵。如果您有一个只产生0和1的引擎,那么您仍然希望uniform_real_distribution产生超过两个值。 - Kerrek SB
1
@kerrek 我以为25.5.1.6是一个IP地址! - brian beuning
显示剩余9条评论
1个回答

2
为此,我增加了一个你没有提到的假设:我假设每个双精度浮点数只进行一次随机抽取。很明显,如果进行两次抽取,你可以获得两倍的随机性。
第一个问题是:"32位伪随机数是否具有足够的随机性来进行光线追踪?" 我的猜测是可以的。大多数光线追踪器只需发射几百万条光线,所以你不会注意到只有40亿个伪随机数的情况。
第二个问题是:"我能否在我关心的双精度值域中分布伪随机性?" 再次,我的猜测是可以的。如果你在一个90度的视场中发射光线,那么从一个伪随机数的抽取中可能有40亿种可能的结果。就比例而言,一个狙击手通过高倍镜观察时看到的角度精度比这些伪随机向量之间的平均差异小几百万倍。
尽管如此,仍需对代码进行性能分析。除非你的场景全部由单个无反射球体组成,否则我会给出99.9998%的概率,即你的光线追踪代码本身所需时间要远远大于伪随机数的生成时间。

你能解释一下如何通过两次抽取获得“两倍的随机性”吗? - More Axes
1
我应该更加精确,即“伪随机性的两倍” int64_t r = rand32() << 32 | rand32() - Cort Ammon
我正在使用浮点数/双精度浮点数进行操作。位运算似乎不太安全,因为浮点数的格式非常敏感。 - More Axes
2
啊,那我说的话就算了。在mt19937和mt19937_64之间没有比你依赖编译器为你定义uniform_real_distribution更重要的后果。你将无法检测到它们之间的结果差异。所有的差异都会在你开始关注如何将PRNG的输出映射到[0,1)时出现。 - Cort Ammon
2
@MoreAxes - 就像CortAmmon所说的那样。uniform_real_distribution将从mt19937中绘制尽可能多的32位值,以生成单个均匀分布的双精度数。这一切都已经为您实现了。 - JohannesD
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接