I have no clue why but my single thread code to calculate PI is much faster than multi. I'm using 500 Million points and for multi-thread 16 cores. With single CPU is fine and multi-thread all 16 Cores are 100% but it's slower...
Any clue??
Single
public static double monteCarloMethodSequencialMethod(long points) {
long inCircle = 0;
for (long i = 0; i < points; i++) {
double x = Math.random();
double y = Math.random();
if(x * x + y * y <= 1) inCircle++;
}
return 4.0 * inCircle / points;
}
Sequencial Monte-Carlo estimated PI value : 3.141562496. Executed in 13432.927304 ms.
Multi-Thread
public double calculatePI() throws InterruptedException, ExecutionException {
double sum = 0;
List<Future<Double>> tasks = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(nProcessors);
for (long i = 0; i < points; i += points / nProcessors) {
Future<Double> task = executor.submit(() -> {
long inCircle = 0;
double val = 0;
for(long k = 0; k < points / nProcessors; k++) {
double x = Math.random();
double y = Math.random();
if(x * x + y * y <= 1) inCircle++;
}
val = 4.0 * inCircle;
return val;
});
tasks.add(task);
}
long pending = nProcessors;
while(pending != 0) {
for(Future<Double> future : tasks) {
if(future.isDone()) {
sum += future.get();
pending--;
System.out.println(pending + " task are still pending");
}
}
}
executor.shutdown();
return sum / points;
}
Concurrent Monte-Carlo estimated PI value : 3.141666048. Executed in 116236.812471 ms.
Java supports single-thread as well as multi-thread operations.
Java has great support for multithreaded applications. Java supports multithreading through Thread class. Java Thread allows us to create a lightweight process that executes some tasks. We can create multiple threads in our program and start them.
Multithreading is the ability of a program or an operating system to enable more than one user at a time without requiring multiple copies of the program running on the computer. Multithreading can also handle multiple requests from the same user.
In your code, you make heavy use of random numbers. Note that java.util.Random
is not ideal in such a situation, as it creates congestion between the threads. That is a known performance issue (source documentation):
Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.
I would recommend to switch to ThreadLocalRandom instead:
java.util.concurrent.ThreadLocalRandom.current().nextDouble()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With