我在非常低的温度下运行模拟薄膜。我尝试使用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
我做错了什么?任务管理器显示正在使用所有处理器,但是呢?
答案 0 :(得分:1)
有几件事:
1)如果查看ExecutorService Javadoc,shutdown()方法不会等待线程完成执行。在您的代码中,您不是在等待任务实际完成。 javadoc还包含一些示例代码,演示如何正确等待ExecutorService完成。
2)基准测试计划并不是一件简单的事情。我可能/可能不信任这里的数字。另请参阅此SO post有关使用Java测量执行时间的信息。另外,我会分别测试你不同类型的执行方法,而不是一次性测试。
3)如果你的任务真的是CPU密集型的。我将创建一个ExecutorService,其线程数与您机器中的核心/处理器数量相匹配。如果你的任务是短暂的,那么线程/上下文切换的额外开销可能不值得,单线程可能是要走的路。