2013-10-03 9 views
5

私はシングルスレッドのJavaコードを使ってアルゴリズムを実装しました。 JITコンパイルを使用してプログラムを実行すると、マシン上に8つのコアすべてが飽和します。 -Xint JVMオプションを使用して同じプログラムを実行してJITコンパイルを無効にすると、期待通りに単一のコアで実行されます。OpenJDK JVM並列化バイトコードはありますか?

これは私のJavaのバージョン情報です:私のコードは並列化されますと、どこがホットスポットは、コードを並列化することができたときの詳細な情報を見つけることができるように

java version "1.7.0_25" 
OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.12.10.2) 
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode) 

なぜそれが思われるのでしょうか?

+0

[現在のHotSpot JVMはデフォルトで並行して動作しますか?](http://stackoverflow.com/questions/ 12219424/does-the-current-hotspot-jvm-run-in-default-by-default) – Boann

+0

GCは並行しています。 –

+0

GCであれば、 '-Xint'を使って同じ結果を得られないのはなぜですか? – user11171

答えて

7

Javaはコードを自動並列化しません。あなたが見ているコアの飽和は、コードをコンパイルするJITです。テストプログラムの入力を大きくして、より長く(おそらく2-3分)実行し、しばらくしてからテールオフするかどうかを確認してください。

+1

私の推測では、 'Concurrent Mark&Sweep' GCが実行されていると思います。 –

+0

これはすでに3〜5秒ほど良いですが、入力を大きくすることができます。実装が非常に小さいため、JITコンパイルは非常に迅速に完了すると私は考えていました。 – user11171

+0

JITを有効にせずに利用できるコアが1つしかないと考えると、GCがすべてのコアを占めているとは思わないでしょう。 – user11171

2

コードを自動的に自動的にパラレル化するわけではありませんが、より多くのマシンリソースを使用してコードをより迅速に実行します。これは、プロファイリング、コンパイル、ガベージコレクション、ランタイムデータに基づいて絶えず再コンパイルしています。可能であれば、これらの操作は他のCPUで実行されます。

これは、そのパラメータの結果を補完するのと同じパラメータで十分なメソッドを呼び出すか、与えられたメソッドのif文が決して取られていない場合はそれを最適化して元の異なるパラメータがある場合これらの操作がプログラムを遅くしたりブロックしたりするのを望まないので、別のスレッドで実行します。

私はあなたがそれが単一のCPUを満たすことに戻ると思うが、十分に長く走ったかどうかは推測できます。

1

上記の回答は、大正解です。私は絵を完成させるために答えるだけです。明らかに、JVMはユーザコードを自動並列化せず、それ自体のスレッドが進行しています。これらのスレッドの数は異なりますが、一般に次のスレッドがあります。このスレッドスタックのスナップショットは、ホットスポット(OpenJDK)JVMのライブフェーズの開始時に取得されます。オクタコアやクアッドコアのすべてのコアを簡単に占有できる11のスレッドがここにあります。スレッド名もその目的を説明します。

Full thread dump OpenJDK 64-Bit Server VM (25.71-b00-debug mixed mode): 

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007ffff0160800 nid=0x2f91 runnable [0x0000000000000000] 

"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007ffff0158800 nid=0x2f90 waiting on condition [0x0000000000000000] 

"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007ffff0156000 nid=0x2f8f waiting on condition [0x0000000000000000] 

"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007ffff0153000 nid=0x2f8e waiting on condition [0x0000000000000000] 

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007ffff0150800 nid=0x2f8d waiting on condition [0x0000000000000000] 

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007ffff014e800 nid=0x2f8c runnable [0x0000000000000000] 

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007ffff0103800 nid=0x2f8b in Object.wait() [0x00007ffff412f000] 

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007ffff00fa000 nid=0x2f8a in Object.wait() [0x00007ffff4230000] 

"main" #1 prio=5 os_prio=0 tid=0x00007ffff000d000 nid=0x2f86 runnable [0x00007ffff7fca000] 

"VM Thread" os_prio=0 tid=0x00007ffff00ef800 nid=0x2f89 runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007ffff015f000 nid=0x2f92 waiting on condition 

同様に、スレッド・スタックの次のスナップショットは、アクションにおけるガベージコレクタを示します。このスナップは、GC起動後に取得されたものです。私はGCの並列実装を実行しているので、GCのために8つのスレッドしかありません(オクタコアマシンでテストしているため、GCスレッドはコアの数に等しいと思います)。

Full thread dump OpenJDK 64-Bit Server VM (25.71-b00-debug mixed mode): 

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007ffff017e800 nid=0xaa1 runnable (no locks) [0x0000000000000000] 

"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007ffff016e800 nid=0xaa0 waiting on condition (no locks) [0x0000000000000000] 

"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007ffff016b800 nid=0xa9f waiting on condition (no locks) [0x0000000000000000] 

"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007ffff0169800 nid=0xa9e waiting on condition (no locks) [0x0000000000000000] 

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007ffff0166000 nid=0xa9d waiting on condition (no locks) [0x0000000000000000] 

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007ffff0164800 nid=0xa9c runnable (no locks) [0x0000000000000000] 

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007ffff0119000 nid=0xa9b in Object.wait() (no locks) [0x00007fffba33d000] 

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007ffff0110000 nid=0xa9a in Object.wait() (no locks) [0x00007fffba43e000] 

"main" #1 prio=5 os_prio=0 tid=0x00007ffff000d000 nid=0xa8b runnable (no locks) [0x00007ffff7fc9000] 

"VM Thread" os_prio=0 tid=0x00007ffff0105000 nid=0xa99 runnable (no locks) 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007ffff0026800 nid=0xa91 runnable (no locks) 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007ffff0028800 nid=0xa92 runnable (no locks) 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007ffff002a800 nid=0xa93 runnable (no locks) 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007ffff002c800 nid=0xa94 runnable (no locks) 

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007ffff002e800 nid=0xa95 runnable (no locks) 

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007ffff0030800 nid=0xa96 runnable (no locks) 

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007ffff0032800 nid=0xa97 runnable (no locks) 

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007ffff0034800 nid=0xa98 runnable (no locks) 

"VM Periodic Task Thread" os_prio=0 tid=0x00007ffff017f800 nid=0xaa2 waiting on condition (no locks) 

結論

スレッドの数は、実行中に変化し、多くのスレッドが生み出したその場で殺されているので、あなたはほとんどどんなに長いJavaプログラムによって使用されているシングルコアを見ることはないだろうそれは動く。

上記の出力は、GDBとopenJDKの内部デバッグAPIを使用して生成されました。もし誰かがこれらのスレッドとその目的についてもっと知りたいのであれば、参考にすることができます:Thread Management in openJDK

関連する問題