我想使用带有多个核心的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。
4.3.1重试建议
与RDRAND指令不同,种子值直接来自熵调节器,调用者可以比生成这些值更快地调用RDSEED。这意味着应用程序必须设计稳健,并为RDSEED调用失败做好准备,因为种子不可用(CF = 0)。
如果只有一个线程不经常调用RDSEED,则随机种子不可能不可用。仅在需求量大的时期,例如当一个线程正在调用时 RDSEED快速连续或多线程同时调用RDSEED,可能发生下溢。但是,因为RDSEED指令没有内置的公平机制,所以无法保证线程的频率 为了获得随机种子,重试该指令,或者可能需要多少次重试。实际上,这取决于CPU上的硬件线程数量以及积极性 他们打电话给RDSEED。
据我所知,每个处理器只有一个种子生成器,因此无法并行生成种子,因为生成种子需要时间,对我来说正确的解决方案似乎是拥有每个核心/超级-thread一次请求一个线程,并让正在调用rdseed
的线程等到它获得种子。
因为我每个线程只需要一个种子
#pragma omp critical
while(!_rdseed32_step(&r));
对我来说似乎是正确的方法。
答案 0 :(得分:1)
它会起作用。万一RNG在运行这段代码的过程中发生故障,它会锁定在一个紧密的循环中,但在现实场景中,它会给你一个随机数,一切都会好起来的。
_rdseed16_step()、_rdseed32_step() 和_rdseed64_step() 遵循RdSeed 指令的语义,即返回CF 中的成功位和目标寄存器中的随机数。因此它可以循环运行以获得所需的随机位。