我不知道为什么,但是我用来计算PI的单线程代码比多线程要快得多。我正在使用5亿点和用于多线程16核。如果使用单CPU很好并且使用多线程,则所有16个核都是100%,但是速度较慢...
有任何线索吗?
单
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;
}
Run Code Online (Sandbox Code Playgroud)
蒙特卡洛序列估计的PI值:3.141562496。在13432.927304 ms中执行。
多线程
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;
}
Run Code Online (Sandbox Code Playgroud)
并行蒙特卡洛估计PI值:3.141666048。在116236.812471 ms中执行。
在您的代码中,您大量使用随机数。请注意,java.util.Random在这种情况下这并不理想,因为它会在线程之间造成拥塞。这是一个已知的性能问题(源文档):
java.util.Random 的实例是线程安全的。但是,跨线程并发使用同一个 java.util.Random 实例可能会遇到争用,从而导致性能不佳。考虑在多线程设计中使用 ThreadLocalRandom。
我建议改用ThreadLocalRandom:
java.util.concurrent.ThreadLocalRandom.current().nextDouble()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
102 次 |
| 最近记录: |