带有多个线程的rdseed指令

时间:2017-02-17 10:54:21

标签: multithreading random x86 openmp rdrand

我想使用带有多个核心的rdseed指令为自定义PRNG生成种子。

以下是我到目前为止使用OpenMP的内容。

//gcc -Wall -O3 -fopenmp -mrdseed myrand.c
#include <x86intrin.h>
#include <stdio.h>
int main(void)  {  
    #pragma omp parallel
    {
        unsigned r;
        #pragma omp critical
        while(!_rdseed32_step(&r));
        //prng_init(r);
        printf("%d\n", r);
    }
}

这是为每个线程生成种子的正确/理想方式吗?我在调用rdseed时是否需要关键部分?如果生成随机值,则_rdseed32_step内在函数返回1,否则返回0。

The Intel DRNP Manual

  

4.3.1重试建议

     

与RDRAND指令不同,种子值直接来自熵调节器,调用者可以比生成这些值更快地调用RDSEED。这意味着应用程序必须设计稳健,并为RDSEED调用失败做好准备,因为种子不可用(CF = 0)。

     

如果只有一个线程不经常调用RDSEED,则随机种子不可能不可用。仅在需求量大的时期,例如当一个线程正在调用时   RDSEED快速连续或多线程同时调用RDSEED,可能发生下溢。但是,因为RDSEED指令没有内置的公平机制,所以无法保证线程的频率   为了获得随机种子,重试该指令,或者可能需要多少次重试。实际上,这取决于CPU上的硬件线程数量以及积极性   他们打电话给RDSEED。

据我所知,每个处理器只有一个种子生成器,因此无法并行生成种子,因为生成种子需要时间,对我来说正确的解决方案似乎是拥有每个核心/超级-thread一次请求一个线程,并让正在调用rdseed的线程等到它获得种子。

因为我每个线程只需要一个种子

#pragma omp critical
while(!_rdseed32_step(&r));

对我来说似乎是正确的方法。

1 个答案:

答案 0 :(得分:1)

它会起作用。万一RNG在运行这段代码的过程中发生故障,它会锁定在一个紧密的循环中,但在现实场景中,它会给你一个随机数,一切都会好起来的。

_rdseed16_step()、_rdseed32_step() 和_rdseed64_step() 遵循RdSeed 指令的语义,即返回CF 中的成功位和目标寄存器中的随机数。因此它可以循环运行以获得所需的随机位。