1

同じ外部実行可能ファイルを6回呼び出す必要があるJavaプログラムがあります。この実行可能ファイルは出力ファイルを生成し、6回の実行がすべて完了したら、これらのファイルを「マージ」します。コードを実行し、外部実行可能ファイルの最初の実行が終了するのを待ってから、もう一度呼び出すなど、forループがありました。

これは非常に時間がかかり、6回実行するのに平均52.4秒かかることがわかりました...特に相互に依存していないため、外部実行可能ファイルを一度に6回実行することで、かなり簡単に高速化できると思いました。 。これを実現するために、などを使用ExecutorServiceRunnableました。

現在の実装では、時間を約5秒短縮し、わずか11%高速化しています。

これが私がしていることを説明するいくつかの(簡略化された)コードです:

private final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();

....

private void setUpThreadsAndRun() {
    ExecutorService executor = Executors.newFixedThreadPool(6);

    for (int i = 0; i < 6; i++) {
        //create the params object
       tasks.add(Executors.callable(new RunThread(params)));
    }

    try {
        executor.invokeAll(tasks);
    } catch (InterruptedException ex) {
        //uh-oh
    }

    executor.shutdown();
    System.out.println("Finished all threads!");
}

private class RunThread implements Runnable {
    public RunThread(ModelParams params) {
        this.params = params;
    }

    @Override
    public void run()
    {
         //NOTE: cmdarray is constructed from the params object
        ProcessBuilder pb = new ProcessBuilder(cmdarray);
         pb.directory(new File(location));
         p = pb.start();
    }
}

これを行うためのより効率的な方法があることを望んでいます...または、このプロセスを一度に6回実行しようとして、コンピューターのリソースを「詰まらせている」可能性があります。このプロセスにはファイルI/Oが含まれ、サイズが約30MBのファイルが書き込まれます。

4

1 に答える 1

2

実行可能ファイルを6回フォークすると、パフォーマンスが向上するのは、少なくとも6つのCPUコアがあり、アプリケーションがCPUにバインドされている場合、つまり、ほとんどがプロセッサ操作を実行している場合のみです。各アプリケーションは30MBのファイルを書き込むため、大量のIOを実行しているように見え、代わりにアプリケーションはIOバウンドになります。これは、IO要求を処理するハードウェアの機能によって制限されます。

プログラムを高速化するために、2つの並行プロセスを試して、改善が得られるかどうかを確認することができます。ただし、プログラムがIOバウンドである場合、複数のコピーをフォークすることによって速度が大幅に向上することはありません。

于 2012-05-09T14:13:20.907 に答える