piを計算するために私のモンテカルロ法を並列化するのに問題があります。ここではforループ並列化されていますpi計算のOpenMP並列化が遅いか間違っている
#pragma omp parallel for private(i,x,y) schedule(static) reduction(+:count)
for (i = 0; i < points; i++) {
x = rand()/(RAND_MAX+1.0)*2 - 1.0;
y = rand()/(RAND_MAX+1.0)*2 - 1.0;
// Check if point lies in circle
if(x*x + y*y < 1.0) { count++; }
}
問題は、私はschedule(dynamic)
を使用している場合、それは私がschedule(static)
を使用する場合は、パイを過小評価し、シリアル実装よりもその遅く、です。私は間違って何をしていますか?私はそれを修正する他の方法を試しました(このように:Using OpenMP to calculate the value of PI)が、シリアル実装よりもずっと遅いです。あなたがCライブラリrand
機能を使用していると仮定すると、事前に
おかげ
'rand()'はスレッドセーフですか? – Mysticial
@Mystical:これはそうではないようです:http://stackoverflow.com/questions/6161322/using-rand-with-multiple-threads-in-c –
私は@Mysticialが正しいアイデアを持っていると思っています。 'rand'は通常、内部的な「シード(seed)」を持ちます。これは、基本的に共有リソースとして機能し、すべての呼び出し時にシリアル化を強制します(そうでない場合は不正確な結果になる)。もし利用可能なら、 'rand_r'または(好ましくは)' drand48_r'を代わりに使ってみてください。あるいは、C++ 11で導入された乱数生成クラスを考えてみましょう。各インスタンスには独自の状態があり、直列化を避ける必要があります(初期化をトリッキーにする可能性があります。 –