【发布时间】:2019-07-14 15:48:21
【问题描述】:
我需要为大学完成一项编程作业。任务是实现一个程序,它返回方程 q² + 3qp + p² = r² (q,p,r 素数) 的所有解。随后,程序将通过并行化来加速。 不幸的是,我们必须使用 BigInteger,所以不要感到惊讶。
这是我写的课程,它可以精确计算这个方程。
public boolean calculateEquation() {
//Equation: p² + 3pq + q² = r²
if (calculatePSquare().add(calculate3TimesPQ()).add(calculateQSquare()).equals(calculateRSquare())) {
System.out.println("p: " + p + " q: " + q + " r: " + r);
}
return calculatePSquare().add(calculate3TimesPQ()).add(calculateQSquare()).equals(calculateRSquare());
}
@Override
public void run() {
calculateEquation();
}
该类的完整代码: https://pastebin.com/wwrDurUT
我的下一步是测试代码并停下来看看并行化是否在以后工作。为了实现并行化,我查看了不同的线程,其中还有一个链接在这里:What is the easiest way to parallelize a task in java?
这是我的结果:
ExecutorService executorService = Executors.newFixedThreadPool(Configuration.instance.maximumNumberOfCores);
ExecutorCompletionService executorCompletionService = new ExecutorCompletionService(executorService);
for (BigInteger pValue : possiblePValues) {
for (BigInteger qValue : possibleQValues) {
for (BigInteger rValue : possibleRValues) {
executorCompletionService.submit(new Thirteen(pValue, qValue, rValue), null);
}
}
}
executorCompletionService.take();
完整代码: https://pastebin.com/kviEnnFH
现在有趣的是,并行化版本只有在任务数量少的情况下才会更快。对于 0-500 之间的所有素数,并行化版本更快。如果我取 0 到 2000 之间的所有素数,结果看起来会很不一样:
0 到 100 之间的所有素数:
未并行化: 任务耗时:110ms
并行化: 任务耗时:64ms
0 到 2000 之间的所有素数:
未并行化: 完成的任务:7797ms
并行化: 完成的任务:25799ms
由于关于该主题的易于理解的资源非常少,而且老实说我不太了解我的代码究竟做了什么,我很惊讶它为什么会这样。
【问题讨论】:
-
为了排除任何意外,我会检查垃圾收集器在执行期间的行为。数字很大,因此您的应用可能大部分时间都花在了 GC 上。
-
完全没有考虑过GC,你有什么例子可以告诉我如何检查它吗?
-
试试
-XX:+PrintGCJVM参数。