違いは何ですか-
newSingleThreadExecutor vs newFixedThreadPool(20)
オペレーティング システムとプログラミングの観点から。
私のプログラムを実行するたびに、newSingleThreadExecutor
私のプログラムは非常にうまく動作し、エンドツーエンドのレイテンシ (95 パーセンタイル) が実現します5ms
。
しかし、プログラムを実行し始めるとすぐに、
newFixedThreadPool(20)
プログラムのパフォーマンスが低下し、エンドツーエンドのレイテンシが見られるようになりました37ms
。
そこで、アーキテクチャの観点から、ここでのスレッド数が何を意味するのかを理解しようとしています。また、選択すべき最適なスレッド数をどのように決定すればよいのでしょうか。
さらに多くのスレッドを使用するとどうなるでしょうか?
誰かがこれらの簡単なことを一般の人にもわかる言葉で説明してくれると、とても助かります。ご協力ありがとうございます。
私のマシンの構成仕様 - 私はLinuxマシンからプログラムを実行しています -
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 45
model name : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz
stepping : 7
cpu MHz : 2599.999
cache size : 20480 KB
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm arat pln pts
bogomips : 5199.99
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 45
model name : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz
stepping : 7
cpu MHz : 2599.999
cache size : 20480 KB
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm arat pln pts
bogomips : 5199.99
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management:
ベストアンサー1
わかりました。理想的には、スレッドがロックされず、互いにブロックされない(互いに独立している)と仮定し、作業負荷(処理)が同じであると仮定すると、プール サイズがRuntime.getRuntime().availableProcessors()
または であるとavailableProcessors() + 1
最良の結果が得られます。
しかし、スレッドが互いに干渉したり、I/Oが関与したりする場合は、アマダールの法則で十分説明できます。ウィキペディアより、
アムダールの法則は、並列化できるプログラムの割合(つまり、並列化の恩恵を受けるプログラムの割合)をP、並列化できない割合(シリアルのまま)を(1 − P)とすると、N個のプロセッサを使用することで達成できる最大の高速化は次の式で表されます。
あなたの場合、利用可能なコアの数と、それらが正確にどのような作業を行うか(純粋な計算? I/O? ロックの保持? 何らかのリソースのブロック? など)に基づいて、上記のパラメータに基づいたソリューションを考え出す必要があります。
たとえば、数か月前、私は多数の Web サイトからデータを収集していました。私のマシンは 4 コアで、プール サイズは でした4
。しかし、操作は純粋に でI/O
、ネット速度もそこそこだったため、プール サイズが のときに最高のパフォーマンスが得られることに気付きました7
。これは、スレッドが計算能力ではなく I/O を競っていたためです。そのため、より多くのスレッドがコアを競い合えるという事実を積極的に活用できました。
PS: Brian Goetz 著の「Java Concurrency in Practice」という本のパフォーマンスの章を読むことをお勧めします。この本では、このような問題が詳細に扱われています。