I have been using random_device rd{}
to generate seeds for my Mersenne-Twister pseudo random number generator mt19937 RNG{rd()}
as have been suggested here. However, it is written in the documentation (comment in the documentations' example code), that "the performance of many implementations of random_device
degrades sharply once the entropy pool is exhausted. For practical use random_device
is generally only used to seed a PRNG such as mt19937
". I have tried testing how big this "entropy pool" is, and for 10^6 number of calls, random_device
returns me more than 10^2 repeating numbers (see my example code and output below). In other words, if I will try using random_device
as a seed to my Mersenne-Twister PRNG, it will generate a solid fraction of repeating seeds.
Question: do people still use random_device
in C++ to generate seeds for PRNG or are there already better alternatives?
My code:
#include <iostream>
#include <random>
#include <chrono>
using namespace std;
int main(){
auto begin = std::chrono::high_resolution_clock::now();
random_device rd{};
mt19937 RNG{ rd() };
int total_n_of_calls = 1e6;
vector<int> seeds;
for(auto call = 0; call < total_n_of_calls; call++){
int call_rd = rd();
seeds.push_back(call_rd);
}
int count_repeats = 0;
sort(seeds.begin(), seeds.end());
for(int i = 0; i < seeds.size() - 1; i++) {
if (seeds[i] == seeds[i + 1]) {
count_repeats++;
}
}
printf("Number of times random_device have been called: %i\n", total_n_of_calls);
printf("Number of repeats: %i\n", count_repeats);
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
printf("Duration: %.3f seconds.\n", elapsed.count() * 1e-9);
return 0;
}
The output:
Number of times random_device have been called: 1000000
Number of repeats: 111
Duration: 0.594 seconds.
Aucun commentaire:
Enregistrer un commentaire