在查看Fork/Join Tutorial之后,我创建了一个用于计算大阶乘的类:
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;
}
}
我的问题是如何确定我细分任务的阈值?我发现了一个关于 fork/join parallelism 的页面,其中指出:
使用 fork/join 并行实现算法时要考虑的主要事项之一是选择阈值,该阈值确定任务是否将执行顺序计算而不是分叉并行子任务。
如果阈值太大,则程序可能无法创建足够的任务来充分利用可用的处理器/内核。
如果阈值太小,则任务创建和管理的开销可能会变得很大。
通常,需要进行一些实验来找到合适的阈值。
那么我需要做哪些实验来确定阈值呢?