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 をあまり頻繁に呼び出していないスレッドが 1 つだけの場合、ランダム シードが使用できない可能性はほとんどありません。1 つのスレッドが立て続けに RDSEED を呼び出している場合や、複数のスレッドが同時に RDSEED を呼び出している場合など、負荷の高い期間にのみ、アンダーフローが発生する可能性があります。ただし、RDSEED 命令には公平性メカニズムが組み込まれていないため、スレッドが命令を再試行する頻度や、ランダム シードを取得するために必要な再試行回数に関する保証はありません。実際には、これは CPU 上のハードウェア スレッドの数と、RDSEED をどれだけ積極的に呼び出しているかによって異なります。

私が理解している限りでは、プロセッサごとにシード ジェネレーターが 1 つしかないため、シードを並行して生成することはできません。シードを生成するには時間がかかるため、正しい解決策は、各コア/ハイパースレッドに要求させることです。一度に 1 つずつスレッドを作成しrdseed、シードを取得するまで呼び出しているスレッドを待機させます。

スレッドごとに必要なシードは 1 つだけなので、

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

私には正しいアプローチのようです。

4

1 に答える 1