设置线程池的理想大小

有什么区别-

newSingleThreadExecutor vs newFixedThreadPool(20)

从操作系统和编程的角度来看。

每当我使用我的程序运行我的程序时,我的程序运行得很好,端到端延迟(第95百分位)就会出现。newSingleThreadExecutor5ms

但是一旦我开始运行我的程序使用 -

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参与,那么Amadhal定律解释得很好。来自维基,

阿姆达尔定律指出,如果P是可以并行的程序的比例(即从并行化中受益),而(1 − P)是不能并行化的比例(保持串行),那么使用N个处理器可以实现的最大加速是

Amadhal law

在您的例子中,基于可用内核的数量,以及它们精确地执行哪些工作(纯计算?输入/输出?握住锁?因某些资源而被阻止?等),您需要根据上述参数提出解决方案。

例如:几个月前,我参与从数字网站收集数据。我的机器是 4 核的,我的池大小为 。但是由于操作纯粹并且我的净速度不错,我意识到我的池大小为具有最佳性能。这是因为,线程不是在为计算能力而战,而是在为I/O而战。因此,我可以利用这样一个事实,即更多的线程可以积极地争夺核心。4I/O7

PS:我建议,通读Brian Goetz的书中的性能 - Java Concurrency in Practice一章。它详细处理了这些问题。


答案 2

所以现在我试图从架构的角度来理解线程数在这里意味着什么?

每个线程都有自己的堆栈内存,程序计数器(如指向下一步执行的指令的指针)和其他本地资源。将它们换掉会损害单个任务的延迟。好处是,当一个线程处于空闲状态时(通常在等待 i/o 时),另一个线程可以完成工作。此外,如果有多个处理器可用,则当任务之间没有资源和/或锁定争用时,它们可以并行运行。

如何确定我应该选择的最佳线程数是多少?

交换价格与避免空闲时间的机会之间的权衡取决于任务外观的小细节(有多少i / o,何时,i / o之间的工作量,使用多少内存来完成)。实验始终是关键。

如果我使用更多数量的线程,会发生什么?

通常首先吞吐量呈线性增长,然后是相对平坦的部分,然后是下降(可能非常陡峭)。每个系统都是不同的。


推荐