Search code examples
concurrencyparallel-processingx10-language

X10 Parallel processing shared variable


Please forgive me if my question is not professional. I am reading tutorials of IBM's x10. Here's the code that computes PI but confuses me:

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;

The program itself is not hard, my question is, since in each countPoints() call it repeatedly calling the argument rand, and before spawn multi-threads, only one rand is created, will different threads share the same rand and incur race condition? If not, why?


Solution

  • Good that you worry about a possible race condition here. It is often overlooked in parallel invocation of random number generators.

    Luckily this example is free of a RNG race condition. Each iteration of the k for-loop creates a new instance of a random number generator (and seeds it) and spawns one thread. Since countPoints calls its own RNG there is no race condition here.