为什么在单线程,双线程和三线程程序中运行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,其中的线程数与机器中的核心数/处理器数相匹配。如果你的任务是短暂的,那么线程/上下文切换的额外开销可能并不值得,而单线程可能是最好的选择。