1

我想使用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 。

英特尔 DRNP 手册

4.3.1 重试建议

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

如果只有一个线程不经常调用 RDSEED,那么随机种子不太可能不可用。只有在需求量大的时期,例如一个线程快速连续调用 RDSEED 或多个线程同时调用 RDSEED 时,才可能发生下溢。但是,由于 RDSEED 指令没有内置公平机制,因此无法保证线程应该多久重试一次指令,或者可能需要重试多少次才能获得随机种子。实际上,这取决于 CPU 上的硬件线程数以及它们调用 RDSEED 的积极程度。

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

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

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

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

4

1 回答 1

1

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

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

于 2021-05-12T04:53:46.420 回答