【发布时间】:2015-06-19 21:44:00
【问题描述】:
我用 Java 编写了一个简单的程序来通过蒙特卡洛方法计算 Pi。由于您需要大量滴水才能使 Pi 变得“精确”,而且它当然会变慢,所以我决定实施多线程。现在我的问题是:有什么方法可以加快计算速度?并且一次只计算每个物理线程一次迭代,还是我的多线程概念完全错误?
代码如下:
public class PiMC{
public static void main(String[] args) {
ExecutorService exec=Executors.newCachedThreadPool();
//Future object is used to get result from a thread
Future<Double> result0=exec.submit(new Thread1());
Future<Double> result1=exec.submit(new Thread1());
Future<Double> result2=exec.submit(new Thread1());
Future<Double> result3=exec.submit(new Thread1());
Future<Double> result4=exec.submit(new Thread1());
Future<Double> result5=exec.submit(new Thread1());
Future<Double> result6=exec.submit(new Thread1());
Future<Double> result7=exec.submit(new Thread1());
try
{
System.out.println(((result0.get() + result1.get() + result2.get() + result3.get() + result4.get()+ result5.get() + result6.get() + result7.get()) / Long.MAX_VALUE) * 4);
}
catch(InterruptedException e){System.out.println(e);}
catch(ExecutionException e){System.out.println(e);}
}
}
class Thread1 implements Callable {
@Override
public Double call() throws Exception {
long drops = Long.MAX_VALUE / 8;
//long drops = 500;
double in = 0;
for (long i = 0; i <= drops; i++) {
double x = Math.random();
double y = Math.random();
if (x * x + y * y <= 1) {
in++;
}
}
return in;
}
}
【问题讨论】:
-
我不明白这个问题。对于初学者, ExecutorService 将默认为逻辑处理器数量的池大小 - 所以如果你只有 2 个内核,那么它只会同时运行两个线程。多线程只会在每个线程的 call/run 方法中运行一次代码。
-
您看不到加速的另一个可能原因是
Math.random()在内部使用相同的java.util.Random实例,这会导致一些资源争用。来自Math.random()的API文档:However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator. -
我为一个 8 核的朋友扩展了它,以便他可以更快地计算它,但他报告说他有 105% 的工作量。我的负荷也很高。两个随机数生成和计算不应该只需要一点线程的容量吗?好的,API的问题可能是一个原因,有没有办法解决这个问题?
-
@Acru 如果您想保持较小的负载,为什么要使用并行计算?多线程当然会最大化 CPU 利用率(如果做得好的话),这就是我们使用并行计算的目的。
-
如果您将 CPU 想象成具有多个入口(这些是核心)的排水管,那就更容易了。每个线程都是您要倒入排水管的一桶水。如果您有 8 个进水口和只有 1 个水桶,那么您将只使用 1/8 的进水口,因为您不能将 1 个水桶中的水同时倒入两个进水口。如果您有 8 个入口和 8 个水桶,则可以充分利用排水管。如果你有 12 个桶,那么地板上总会有 4 个排成一列,等待清空。
标签: java multithreading montecarlo pi