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 をあまり頻繁に呼び出していないスレッドが 1 つだけの場合、ランダム シードが使用できない可能性はほとんどありません。1 つのスレッドが立て続けに RDSEED を呼び出している場合や、複数のスレッドが同時に RDSEED を呼び出している場合など、負荷の高い期間にのみ、アンダーフローが発生する可能性があります。ただし、RDSEED 命令には公平性メカニズムが組み込まれていないため、スレッドが命令を再試行する頻度や、ランダム シードを取得するために必要な再試行回数に関する保証はありません。実際には、これは CPU 上のハードウェア スレッドの数と、RDSEED をどれだけ積極的に呼び出しているかによって異なります。
私が理解している限りでは、プロセッサごとにシード ジェネレーターが 1 つしかないため、シードを並行して生成することはできません。シードを生成するには時間がかかるため、正しい解決策は、各コア/ハイパースレッドに要求させることです。一度に 1 つずつスレッドを作成しrdseed
、シードを取得するまで呼び出しているスレッドを待機させます。
スレッドごとに必要なシードは 1 つだけなので、
#pragma omp critical
while(!_rdseed32_step(&r));
私には正しいアプローチのようです。