私は並列で実行しようとしているコードを持っています。GSL + OMP:C++のスレッドセーフ乱数ジェネレータ
#include<iostream>
#include<omp.h>
#include<math.h>
#include<cstdlib>
#include<iterator>
#include<string.h>
#include<vector>
#include<map>
#include<time.h>
#include<gsl/gsl_rng.h>
#include<gsl/gsl_randist.h>
gsl_rng ** threadvec = new gsl_rng*[omp_get_num_threads()];
using namespace std;
int main(){
clock_t begin = omp_get_wtime();
vector<double> PopVals;
map<int, vector<double> > BigMap;
int Num1 = 100;
double randval;
int Num2 = 10;
#pragma omp parallel
{
gsl_rng_env_setup();
for (int b = 0; b < omp_get_num_threads(); b++)
threadvec[b] = gsl_rng_alloc(gsl_rng_taus);
}
for(int i = 0; i < Num1; i++){
PopVals.resize(Num2);
#pragma omp parallel for
for(int j = 0; j < Num2; j++){
randval = gsl_rng_uniform(threadvec[omp_get_thread_num()]);
PopVals[j] = randval;
}
BigMap.insert(make_pair(i,PopVals));
PopVals.clear();
}
map<int,vector<double> >::iterator it = BigMap.find(Num1-1);
vector<double> OutVals = it->second;
for (int i = 0; i < Num2; i++)
cout << endl << OutVals[i] << endl;
for (int b = 0; b < omp_get_num_threads(); b++)
gsl_rng_free(threadvec[b]);
clock_t end = omp_get_wtime();
double elapsed_time = double(end - begin);
cout << endl << "Time taken to run: " << elapsed_time << " secs" << endl;
}
これを実行すると、ネストループを並列に実行するスレッドが8つありますが、スレッドごとに同じ乱数が表示され続けます。私はこの行動が、各反復のために、種子を設定することの欠如に起因すると考えた。スレッドの安全な方法でループの各反復で一意の乱数を生成するにはどうすればいいですか?
上記のコードの出力は、0.793816,10倍です。一方、内側のループの各値に固有の数値が必要です。
ありがとうございました。
どうもありがとう:終わり
が、それは次のようになります!これは正しかった! 1つの質問のみ:「名前空間の使用」を使用できない理由 – peacefrog
[なぜ「名前空間の標準を使用していますか」が悪い習慣と考えられるのですか?](https://stackoverflow.com/q/1452721/620382) - 上位2つをチェックしてください答え。 – Zulan
パラレルコードで乱数を使用することに真剣に取り組んでいる場合は、「パラレル乱数:1、2、3のように簡単」とお読みください。https://pdfs.semanticscholar.org/38bc/7fc62136ec779d91b86b6e960a06d67b4a97.pdf –