After looking the Fork/Join Tutorial, I created a class for computing large factorials:
public class ForkFactorial extends RecursiveTask<BigInteger> {
final int end;
final int start;
private static final int THRESHOLD = 10;
public ForkFactorial(int n) {
this(1, n + 1);
}
private ForkFactorial(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected BigInteger compute() {
if (end - start < THRESHOLD) {
return computeDirectly();
} else {
int mid = (start + end) / 2;
ForkFactorial lower = new ForkFactorial(start, mid);
lower.fork();
ForkFactorial upper = new ForkFactorial(mid, end);
BigInteger upperVal = upper.compute();
return lower.join().multiply(upperVal);
}
}
private BigInteger computeDirectly() {
BigInteger val = BigInteger.ONE;
BigInteger mult = BigInteger.valueOf(start);
for (int iter = start; iter < end; iter++, mult = mult.add(BigInteger.ONE)) {
val = val.multiply(mult);
}
return val;
}
}
The question I have is how to determine the threshold for which I subdivide the task? I found a page on fork/join parallelism which states:
One of the main things to consider when implementing an algorithm using fork/join parallelism is chosing the threshold which determines whether a task will execute a sequential computation rather than forking parallel sub-tasks.
If the threshold is too large, then the program might not create enough tasks to fully take advantage of the available processors/cores.
If the threshold is too small, then the overhead of task creation and management could become significant.
In general, some experimentation will be necessary to find an appropriate threshold value.
So what experimentation would I need to do in order to determine the threshold?