Я использовал функцию rand()
для генерации псевдослучайных чисел между 0,1 для целей симуляции, но когда я решил сделать мой C++ код запущенным параллельно (через OpenMP), я заметил, что rand()
безопасный, а также не очень однородный.
Поэтому я переключился на использование (так называемого) более однородного генератора, представленного во многих ответах по другим вопросам. Что выглядит так
double rnd(const double & min, const double & max) {
static thread_local mt19937* generator = nullptr;
if (!generator) generator = new mt19937(clock() + omp_get_thread_num());
uniform_real_distribution<double> distribution(min, max);
return fabs(distribution(*generator));
}
Но я видел много научных ошибок в моей оригинальной проблеме, которую я имитировал. Проблемы, которые были как против результатов rand()
и против здравого смысла.
Поэтому я написал код для генерации случайных чисел 500k с этой функцией, вычислил их среднее значение и сделал это в 200 раз и построил результаты.
double SUM=0;
for(r=0; r<=10; r+=0.05){
#pragma omp parallel for ordered schedule(static)
for(w=1; w<=500000; w++){
double a;
a=rnd(0,1);
SUM=SUM+a;
}
SUM=SUM/w_max;
ft<<r<<'\t'<<SUM<<'\n';
SUM=0;
}
Мы знаем, что вместо 500k я мог бы делать это бесконечно, это должна быть простая строка со значением 0.5. Но с 500 тыс. Мы будем иметь колебания около 0,5.
При запуске кода с одним потоком результат допустим:
Но вот результат с двумя потоками:
3 темы:
4 темы:
У меня нет моего 8-поточного процессора прямо сейчас, но результаты даже стоили там.
Как вы можете видеть, они оба неравномерны и очень колеблются вокруг их среднего.
Так же ли это псевдослучайный генераторный поток - небезопасный?
Или я что-то ошибаюсь?