为什么运行 ExecutorService 在单线程、双线程和三线程程序中耗时相同?

Why does running ExecutorService in single, dual and triple threaded program take the same time?

我正在 运行在极低的温度下模拟薄膜。我尝试使用 ExecutorService 正确地对我的代码进行多线程处理,并希望减少 运行 时间。但我发现这说起来容易做起来难。我摆弄了许多参数,但无法提高任何效率。我发现奇怪的是,运行使用单线程、双线程或三线程 ExecutorService 执行代码几乎花费相同的时间。

底线是,尽管 for 循环的更多迭代同时 运行ning 并行,但 运行 单次迭代所花费的时间增加了。无论使用多少处理器,总 运行时间几乎相同。

我很困惑。我做错了什么?

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,shutdown() 方法不会等待线程完成执行。在您的代码中,您不是在等待任务实际完成。 javadoc 还包含一些示例代码,演示如何正确等待 ExecutorService 完成。

2) 基准测试程序并不是一件简单的事情。我 may/may 不相信这里的数字。另请查看 SO post 关于在 Java 中测量执行时间的内容。另外,我会分别测试您的不同类型的执行方法,而不是一次全部测试。

3) 如果您的任务确实 CPU 密集。我会创建一个 ExecutorService,其线程数与您机器中的 cores/processors 数相匹配。如果您的任务是短暂的,那么 threading/context 切换的额外开销可能不值得,单线程可能是可行的方法。