3

私はJavaでマルチスレッドを扱っていますが、誰かが私に指摘したように、スレッドがウォームアップすることに気付きました。つまり、繰り返し実行されるとスレッドが速くなります。これが発生する理由と、それが Java 自体に関連するものなのか、それともすべてのマルチスレッド プログラムに共通する動作なのかを理解したいと思います。

それを例示するコード (Peter Lawrey による) は次のとおりです。

for (int i = 0; i < 20; i++) {
    ExecutorService es = Executors.newFixedThreadPool(1);
    final double[] d = new double[4 * 1024];
    Arrays.fill(d, 1);
    final double[] d2 = new double[4 * 1024];
    es.submit(new Runnable() {
    @Override
    public void run() {
        // nothing.
    }
    }).get();
    long start = System.nanoTime();
    es.submit(new Runnable() {
    @Override
    public void run() {
        synchronized (d) {
            System.arraycopy(d, 0, d2, 0, d.length);
        }
    }
    });
    es.shutdown();
    es.awaitTermination(10, TimeUnit.SECONDS);
    // get a the values in d2.
    for (double x : d2) ;
    long time = System.nanoTime() - start;
    System.out.printf("Time to pass %,d doubles to another thread and back was %,d ns.%n", d.length, time);
}

結果:

Time to pass 4,096 doubles to another thread and back was 1,098,045 ns.
Time to pass 4,096 doubles to another thread and back was 171,949 ns.
 ... deleted ...
Time to pass 4,096 doubles to another thread and back was 50,566 ns.
Time to pass 4,096 doubles to another thread and back was 49,937 ns.

つまり、より高速になり、約 50 ns で安定します。何故ですか?

このコードを実行し (20 回の繰り返し)、別の何かを実行し (前の結果の後処理と別のマルチスレッド ラウンドの準備をしましょう)、後で同じコードをさらに 20 回繰り返し実行するとRunnableThreadPool既にウォームアップされます。どのような場合ですか?

私のプログラムでは、Runnable1 つのスレッド (実際には私が持っているプロセッシング コアごとに 1 つ、CPU を集中的に使用するプログラム) で実行し、次に他のシリアル処理を何度も交互に実行します。プログラムが進むにつれて速くなるようには見えません。温める方法が見つかるかもしれません…</p>

4

2 に答える 2

9

JVMほどウォーミングアップしているのはスレッドではありません。

JVMには、JIT(Just In Time)コンパイルと呼ばれるものがあります。プログラムの実行中に、プログラムで何が起こっているかを分析し、その場で最適化します。これは、JVMが実行するバイトコードを取得し、それをより高速に実行されるネイティブコードに変換することによって行われます。実際の実行時の動作を分析することでこれを行うため、現在の状況に最適な方法でこれを行うことができます。これにより、(常にではありませんが)優れた最適化が可能になります。そのような知識なしにネイティブコードにコンパイルされるいくつかのプログラムよりもさらにそうです。

あなたはhttp://en.wikipedia.org/wiki/Just-in-time_compilationでもう少し読むことができます

コードがCPUキャッシュにロードされると、どのプログラムでも同様の効果が得られる可能性がありますが、これは小さな違いになると思います。

于 2011-03-04T20:00:01.913 に答える
1

スレッドの実行が最終的に高速になる唯一の理由は次のとおりです。

  • メモリ マネージャーは、既に割り当てられているオブジェクト スペースを再利用できます (たとえば、最大メモリに達するまで、ヒープ割り当てによって使用可能なメモリがいっぱいになるようにします -Xmxプロパティ) 。

  • ワーキング セットはハードウェア キャッシュで利用可能です

  • 操作を繰り返すと、コンパイラが実行を最適化するために簡単に並べ替えることができる操作が作成される場合があります

于 2011-03-04T20:00:41.547 に答える