Actually I wrote a Java program for calculating a particular number on the Fibonacci series.
The problem is right now is that I am using number of cores as number of threads required. But I have observed that as the input size increases I get better performance by increasing the number of threads.
Is there an existing formula/Theory on how to divide the problem into multiple threads?
Below is the source code:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Fibonacci {
private static long[] value;
public static void main(String args[]) throws InterruptedException {
int n;
try {
n = Integer.parseInt(args[0]);
} catch (Exception e) {
throw new RuntimeException(
"Please enter in the form java n number ");
}
value = new long[n + 1];
long start = System.nanoTime();
int nThreads = Runtime.getRuntime().availableProcessors();
ExecutorService executorService = Executors
.newFixedThreadPool(nThreads);
int result;
try {
result = fibonacciSum(n, executorService);
} catch (ExecutionException e) {
throw new RuntimeException("Thread Interuppted ");
}
System.out.print(" MultiThreading = " + result);
long end = System.nanoTime();
System.out.println("\t time = " + (end - start) + "ns");
}
private static class FibonacciThread implements Runnable {
int index;
int result;
ExecutorService executorService;
public FibonacciThread(int index) {
this.index = index;
}
public void run() {
try {
this.result = fibonacciSum(index, executorService);
} catch (Exception e) {
throw new RuntimeException("Thread interupted");
}
}
}
private static int fibonacciSum(int index, ExecutorService executorService)
throws InterruptedException, ExecutionException {
if (index <= 2) {
return 1;
} else {
FibonacciThread fibonacciThread1 = new FibonacciThread(index - 2);
fibonacciThread1.executorService = executorService;
Future future = executorService.submit(fibonacciThread1);
Object object = future.get();
int resultPart2 = fibonacciSum(index - 1, executorService);
int result = fibonacciThread1.result + resultPart2;
// executorService.shutdown();
return result;
}
}
}
In case you haven’t already realized this, Fibonacci numbers are not a good candidate for parallelization. You will get (increasingly) better performance:
The basic problem is that the naive Fibonacci calculation requires an exponential number of computation steps. You can’t make an impact on that (in terms of performance) with multi-threading because you have a bounded number of processors.
Even if you did have an infinite number of processors, the thread setup / task creation overheads exceed the time for doing a step in the calculation.
Finally, there is a particular problem with doing Fibonacci using the executor service and a bounded thread pool. If the thread pool is too small (or N is too large) the computation is liable to get stuck. For instance, the way that you’ve coded it needs
~Nthreads in the pool to calculatefibonacci(N), even though most of them will be blocked most of the time. (The best way to understand this is to “hand execute” the application, paying attention to how many threads are in use at each point in time … and what they are doing.)So the simple answer to your question is (for this particular application) that you need at least
Nthreads in the pool to even complete the computation ofFibonacci(N). (This is not a general answer. It is mandated by the details of the algorithm that you’ve implemented.)There are lots of other SO questions / answers on calculating Fibonacci numbers using threads. I suggest you read them as well.