首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从/dev/{随机,urandom}快速生成并行随机数

从/dev/{随机,urandom}快速生成并行随机数
EN

Stack Overflow用户
提问于 2014-05-11 11:05:30
回答 1查看 809关注 0票数 0

我有这样的科学研究代码:

代码语言:javascript
复制
    #define TRIALS 1000000
    #define LEN 10
    int i;
    for(i=0;i<TRIALS;i++) {
        uint8_t r[LEN];
        getRand(r, LEN);
        doExperiment(r);
    }

其中我使用/dev/urandom获取随机数:

代码语言:javascript
复制
    void getRand(uint8_t *r, int len) {
        int rand = open("/dev/urandom", O_RDONLY);
        read(rand, r, len);
        close(rand);
    }

注:我不要求我的实验是可重复的,所以不关心有一个固定的种子。然而,关键的任务是我的随机数是高质量的(相当接近密码安全),所以我的结果的统计数据是有效的。速度也很重要。

我计划将这段代码并行化,首先使用OpenMP,只需在循环前面插入一个#pragma omp parallel for即可。

问题:,并发生成随机数的最佳方法是什么(尽管建议不要使用/dev/urandom)?我是否应该在调用getRand()时设置一个互斥,并允许我的代码在获取随机数时序列化,我应该尝试预先生成所需的所有随机数,还是应该有一个单独的线程来填充随机数字的缓冲区,该缓冲区是以生产者-消费者的方式(用互斥锁)读取的?如果我使用/dev/随机的方法,这是一个有限的资源,可能会阻塞,那么最好的解决方案会有所不同吗?

我已经阅读了关于并行生成随机数的相关文章,但我希望专门讨论一个关于使用/dev/{urandom,随机}的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-11 15:15:19

为了巩固一些评论..。

对一个从/dev/urandom读取的getRand()函数进行多次调用是缓慢的,应该避免,因为它使用了增加大量开销的系统调用。最好从/dev/urandom中读取更大的块并对它们进行缓冲,或者使用/dev/urandom为软件PRNG注入种子。

在后一种情况下,可以使用OpenSSL的RAND_bytes()返回“加密强随机”值。这可以配置为使用英特尔的DRNG通过RDRAND指令(参见Numbers#Hardware),这是讨论的这里。这实际上是通过AES-NI指令集(也可以通过OpenSSL的EVP API直接访问)在计数器模式下使用AES的硬件实现。据英特尔 --支持RDRAND的OpenSSL版本比非RDRAND版本的性能高出一个数量级.

用于为多个线程生成随机数的两种方法(在这个职位中讨论)要么为/dev/urandom中的每个线程设置一个独立的PRNG,要么从/dev/urandom为一个PRNG种子,然后从该线程中为每个线程的PRNG注入种子。

但是应该注意的是,OpenSSL并不是线程安全的这个职位给出了一个将OpenSSL与OpenMP结合使用的良好示例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23591801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档