问:如果一个和尚挑水喝,两个和尚抬水喝,三个和尚没水喝,那么众人拾柴一定火焰高吗?
多线程一定能提高程序性能吗?在计算机科学中,这个问题的标准答案是“it depends”,看情况。
计算机中的一切设计都是为了更加高效地利用硬件资源,包括:cpu、内存、io等,我们一样一样来了解一下。
多线程与cpu
多线程与cpu是程序员了解得最多的,我们知道多线程的目的之一在于充分利用多核,但这里有个前提就是你要处理的任务真的能拆分成独立的子任务。 举个例子,如果你想求一个数组所有元素的和,那么这个任务就可以拆分成为两个独立的子任务:任务a计算前一半数组元素的和,任务b计算后一半数组元素的和,然后任务a和任务b分别交给两个线程来执行。 如果是在多核系统下,这类多线程并行处理将显著提高程序性能,但这种使用多线程充分利用多核带来的性能提升是有上限的。 道理很简单,这就好比盖房子,盖房子算是个不大不小的工程,让一个人来完成也不是不可以,但再来六七个人显然能加快工程速度,但是再来成百上千工人来盖一栋房子可能速度反而会变慢,毕竟资源是有限的(可用的工具等),人一多需要用在协调上的时间就会变多,多线程也是同样的道理,当线程数量超过某个临界点时,操作系统就开始忙不过来了(频繁调度切换),我称之为三个和尚没水喝现象。 但如果系统是单核的,那么这种任务拆分则不会有什么效果,因为不管创建多少线程,真正工作的cpu只有一个。 当然也有可能我们根本就不能对任务进行拆分,像计算斐波那契数列这类问题,如果不能计算出f(n-1)与f(n-2)的解,那么根本就没有办法计算出当前问题f(n)的解,被拆分的两个任务a和b有前后依赖关系,这时多线程就没有用武之地了。 还有一种可能,就是问题规模非常小,如果这个数组是有几百几千个元素,那么这时使用多线程意义不大,这时使用多线程带来的收益不足以抵消掉多线程带来的性能开销。
多线程与io
多线程一定能提升程序的io性能吗?答案显然不是的。 最简单的场景是这样的,你的程序需要从一个速度极慢的网络链接上读写数据,在这种情况下,一个线程很可能就足以应付得过来,创建多个线程反而可能对程序性能有损。 相同的情况也会出现在磁盘上,一个线程可能就已经将磁盘打满,这时创建多个线程去读写文件显然不能加快程序的处理速度。 而在服务器端,程序员也使用多线程加快程序处理速度,在这里,一个典型的问题是阻塞式网络io会导致调用线程被挂起而暂停运行,此时最简单的方法就是创建多个线程,每个线程处理一个请求,但随着请求的增多,创建的线程也会越来越多,此时三个和尚没水喝现象开始出现,io多路复用技术可以很好地解决这一问题。 当然,如果你的场景是io会阻塞住处理线程,那么此时创建两个线程,一个负责处理数据,一个负责等待io,那么这显然会提高程序性能。
多线程与内存
内存其实和磁盘一样,也是有读写带宽上限的,但我们的程序一般都不会达到内存读写带宽上限,这并不是瓶颈。 瓶颈在于多线程共享的内存资源(数据)以及多核系统的cache一致性问题。 一般来说,对于多线程共享资源通常需要互斥访问,然而为加快内存读写速度,现代处理器中都有cache系统(l1、l2、l3),每个核心都有自己的cache,这些cache会缓存内存数据,也就是说一份数据可能会同时存在于内存以及各个核心的cache中,这就会带来经典的数据一致性问题:某个核心修改了cache中的数据后需要将其同步给其他核心,这就要求cache系统中必须有能确保一致性的协议,否则程序可能会读取到错误的(过期的)数据。 然而这种同步是有性能损耗的,多个线程频繁操作同一个变量可能导致处理器cache系统需要频繁在各个核心之间进行同步,极端情况下多线程程序性能甚至比单线程要差。 因此多线程之间能不共享数据就不要共享,如果一定要共享,那么就尽量将其控制在最小范围,读写频次控制到最少。
可穿戴PCB设计的设计说明
工业机器人正在走向轻量化与智能化
2020年,新兴产业提振了机器人的复苏
小米7概念图曝光:94%屏占比+4K分辨率+骁龙845处理器
长电科技与行业伙伴合作开发高标准UWB产品
多线程一定能提高程序性能吗
立磨辊皮磨损的常见原因及修复方法
防爆高低温试验箱可以用在哪些领域
松下A300MU型DVD机开关电源集成电路
如何通过Zigbee技术或Thread协议快速构建网状连接照明应用
医疗健康产品大盘点
CC2530 芯片介绍
ddr3及ddr4的差异对比
通用AI与窄AI之间有何不同?
倾角传感器的典型应用范围
关于USB连接器使用Type-C母座的优点和缺点
微雪电子树莓派红外夜视监控摄像头介绍
aigo国民好物固态硬盘P3000安装很简单,一看就会
2021年全球UWB出货量预计将达到2亿个以上
华为辟谣退出美国市场裁撤全部据点的消息