如何设置合适的线程数,首先要分析以下两个问题:
- 为什么要使用多线程
- 多线程的应用场景有哪些
一
使用多线程,本质上就是提升程序性能。 那如何度量性能呢?核心指标有两个。
延迟 指的是发出请求到收到响应这个过程的时间;延迟越短,意味着程序执行得越快,性能也就越好。
吞吐量 指的是在单位时间内能处理请求的数量;吞吐量越大,意味着程序能处理的请求越多,性能也就越好。
这两个指标内部有一定的联系(同等条件下,延迟越短,吞吐量越大),但是由于它们隶属不同的维度(一个是时间维度,一个是空间维度),并不能互相转换。 提升性能,就是降低延迟,提高吞吐量。也是我们使用多线程的主要目的。
二
怎么降低延迟,提高吞吐量呢?作者认为有两个方向:优化算法,提升硬件的性能。
在并发编程领域,提升性能本质上就是提升硬件的利用率,再具体点来说,就是提升 I/O 的利用率和 CPU 的利用率。那如何利用多线程来提升 CPU 和 I/O 设备的利用率呢?
详见专栏中的单线程执行示意图、二线程执行示意图与多核执行多线程示意图。
三
作者给出了不同应用场景下计算最佳线程数的公式。
- 对于 CPU 密集型的计算场景
- 理论上“线程的数量 = CPU 核数”就是最合适的。不过在工程上,线程的数量一般会设置为“CPU 核数 + 1”。
- 对于 I/O 密集型的计算场景
- 针对单核 CPU,最佳线程数 = 1 +(I/O 耗时 / CPU 耗时)
- 针对多核 CPU,最佳线程数 = CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]
对于 I/O 密集型计算场景,I/O 耗时和 CPU 耗时的比值是一个关键参数,不幸的是这个参数是未知的,而且是动态变化的,所以压测时,我们需要重点关注 CPU、I/O 设备的利用率和性能指标(响应时间、吞吐量)之间的关系。
四
最后,作者认为线程数不是越多越好,但是设置多少是合适的,只要把握住一条原则就可以了,这条原则就是将硬件的性能发挥到极致。