为什么在单线程,双线程和三线程程序中运行ExecutorService的时间相同?
问题描述:
我正在非常低的温度下运行薄膜模拟。我尝试使用ExecutorService正确地多线程我的代码,并希望减少运行时间。但是我发现了这种说起来容易做起来难的难办法。我摆弄了许多参数,但无法提高效率。我发现奇怪的是,使用单线程,双线程或三线程ExecutorService运行代码的时间几乎相同。为什么在单线程,双线程和三线程程序中运行ExecutorService的时间相同?
底线是,尽管for循环的更多迭代同时并行运行,但运行单个迭代所花费的时间却增加了。无论使用多少个处理器,整体运行时间几乎相同。
我很困惑。我究竟做错了什么?
public abstract class IsingRun {
public static void main(String[] args) {
long starta = System.currentTimeMillis(); //time for single thread
for (double t=temp[1];t<=temp[0] ;t+=temp[2]) {
long start = System.currentTimeMillis();
//do stuff
start = System.currentTimeMillis()-start;
print(t,output,start); //start is the time taken for single iteration
}
starta = System.currentTimeMillis()-starta;
System.out.println("Total Runtime (Single): "+ starta); //single thread total time
/*end of single threaded process */
long startb = System.currentTimeMillis();
ExecutorService e = Executors.newFixedThreadPool(2);
for (double t=temp[1];t<=temp[0] ;t+=temp[2]) {
simulate s = new simulate(t);
e.execute(s);
}
e.shutdown();
startb = System.currentTimeMillis()-startb;
System.out.println("Total Runtime (Double): "+ startb);
/*end of double threaded process */
long startc = System.currentTimeMillis();
e = Executors.newFixedThreadPool(3);
for (double t=temp[1];t<=temp[0] ;t+=temp[2]) {
simulate s = new simulate(t);
e.execute(s);
}
e.shutdown();
startc = System.currentTimeMillis()-startc;
System.out.println("Total Runtime (Triple): "+ startc);
/*end of triple threaded process */
}
}
class simulate implements Runnable{
simulate(double T){this.t=T;};
public void run() {
long start = System.currentTimeMillis();
//do stuff
start = System.currentTimeMillis()-start;
print(t,output,start); //start is the time taken for single iteration
}
}
我得到了以下结果
Temp - Output - Runtime for single iteration
2.10 - 0.85410 - 632288
2.20 - 0.83974 - 646527
2.30 - 0.81956 - 655128
2.40 - 0.80318 - 645012
2.50 - 0.79169 - 649863
2.60 - 0.77140 - 662429
Total Runtime (Single): 3891257
2.10 - 0.85585 - 1291943
2.20 - 0.83733 - 1299240
2.40 - 0.80284 - 1313495
2.30 - 0.82294 - 1334043
2.50 - 0.79098 - 1315072
2.60 - 0.77341 - 1338203
Total Runtime (Double): 3964290
2.10 - 0.85001 - 1954315
2.20 - 0.84137 - 1971372
2.30 - 0.82196 - 1996214
2.40 - 0.80684 - 1966009
2.50 - 0.78995 - 1970542
2.60 - 0.77437 - 1966503
Total Runtime (Triple): 3962763
我在做什么错?任务管理器显示所有处理器正在使用,但是它?
答
几件事情:
1)如果你看一看的ExecutorService Javadoc,关机()方法不会等待线程完成执行。在你的代码中,你并没有等待任务真正完成。 javadoc还包含一些示例代码,演示如何正确等待ExecutorService完成。
2)基准程序并不是一个简单的事情。我可能/不可以相信这里的数字。关于在Java中测量执行时间,也请看这SO post。另外,我会分别测试你的不同类型的执行方法,而不是一次性完成。
3)如果你的任务真的是CPU密集型的。我将创建一个ExecutorService,其中的线程数与机器中的核心数/处理器数相匹配。如果你的任务是短暂的,那么线程/上下文切换的额外开销可能并不值得,而单线程可能是最好的选择。