2

私の質問が専門家でない場合はご容赦ください。私はIBMのx10のチュートリアルを読んでいます。PIを計算するが、私を混乱させるコードは次のとおりです。

public static def countPoints(n: Int, rand: ()=>Double) {
 var inCircle: Double = 0.0;
 for (var j:Long = 1; j<=n; j++) {
    val x = rand();
    val y = rand();
    if (x*x +y*y <= 1.0) inCircle++;
 }
    return inCircle;
}

val N = args.size() > 0 ? Long.parse(args(0)) : 100000;
 val THREADS = args.size() > 1 ? Int.parse(args(1)) : 4;
 val nPerThread = N/THREADS;
 val inCircle = new Array[Long](1..THREADS);
 finish for(var k: Int =1; k<=THREADS; k++) {
     val r = new Random(k*k + k + 1);
     val rand = () => r.nextDouble();
     val kk = k;
     async inCircle(kk) = countPoints(nPerThread,rand);
 }
 var totalInCircle: Long = 0;
 for(var k: Int =1; k<=THREADS; k++) {
     totalInCircle += inCircle(k);
}
val pi = (4.0*totalInCircle)/N;

プログラム自体は難しくありません。私の質問は、各countPoints()で引数randを繰り返し呼び出すため、マルチスレッドを生成する前に、1つのrandのみが作成され、異なるスレッドが同じrandを共有し、競合状態が発生するのでしょうか。そうでない場合、なぜですか?

4

1 に答える 1

2

ここで競合状態の可能性を心配するのは良いことです。乱数ジェネレータの並列呼び出しでは見落とされがちです。

幸い、この例にはRNGの競合状態はありません。forループを繰り返すたびにk、乱数ジェネレーターの新しいインスタンスが作成され(そしてシードされ)、1つのスレッドが生成されます。countPoints独自のRNGと呼ばれるため、ここでは競合状態はありません。

于 2013-01-25T22:16:23.300 に答える