我想使用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 的积极程度。
据我了解,每个处理器只有一个种子生成器,因此无法并行生成种子,并且由于生成种子需要时间,因此对我来说正确的解决方案似乎是让每个核心/超线程请求一个一次一个线程,并让正在调用的线程rdseed
等待,直到它获得种子。
因为我每个线程只需要一个种子然后
#pragma omp critical
while(!_rdseed32_step(&r));
对我来说似乎是正确的方法。