在多线程上下文中,与erand48()一样快的随机生成器的替代方案?

时间:2019-05-07 10:02:54

标签: c multithreading random thread-safety

我有一个多线程程序,其中每个线程都调用函数erand48()来生成随机数。每个线程都有自己的私有随机种子,因此不会共享该种子。但是,erand48()不是规范中所说的线程安全的。

我尝试用erand48()替换random(),这是线程安全的,但是它要慢得多,性能是我的首要考虑。

我还要指定我不知道预先生成的值的数量,因此我无法像其他博客所建议的那样预先生成所有值

erand48()会不会有最快的替代方法并且是线程安全的?

2 个答案:

答案 0 :(得分:3)

  

但是,erand48()并不是规范中所说的线程安全的。

这是错误的,erand48()是专门作为drand48()的线程安全版本制作的。引用Open Group

  

通过使用不同的参数,erand48(),nrand48()和jrand48()允许   大型程序的单独模块以生成几个独立的   伪随机数流,即   每个流将不取决于例程有多少次   调用以为其他流生成数字。

您只需要确保在每个线程中“播种”它,也许可以按以下说明进行操作:https://stackoverflow.com/a/26353855/4454124


更新:根据POSIX,erand48()和类似的功能应该是线程安全的,但是似乎they are not in glibc确实会修改全局随机生成器状态缓冲区。为了确保线程安全,您可以使用*_r variants,它是GNU扩展名。生成器状态缓冲区通过这些函数传递。

答案 1 :(得分:1)

您考虑过使用代码吗?您没有说想要一个随机数生成器有多好。在许多统计测试中,random()的较早版本都不认为是很好的。

如果您在Wikipedia上查找“随机数生成器列表”,则在其底部的Wikipedia页面的链接中将“ Xoroshiro128 +”描述为“现代64位CPU上最快的生成器之一”。在“实现”部分,您会找到列出的几个版本,包括C语言中的一个。也许可以通过修改将其合并到您的代码中,以确保它是线程安全的(无静态变量)?

这里有一篇关于线程安全代码的文章 https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.genprogc/writing_reentrant_thread_safe_code.htm

在这里使用线程安全随机数生成器 https://gist.github.com/carc1n0gen/1c3fe2fa5f1312993e1d