四十个小活儿:核数 1→4,总耗时腰斩再腰斩,平均周转也一起变好。但一个不可拆的大活儿:核数从 1 加到 4,一拍都没省。并行不是万能的,它只对【能拆】的活儿有效。
4.14 看到了天花板,这一节看另一面:能拆的活儿,多核确实能同时改善吞吐与延迟;不能拆的,一点都改不了。
一、大批小活儿:多核真能两头都好
四十个各 2 拍的活儿,核数 1/2/4。 总耗时大致按核数下降,平均周转也跟着降——因为每个活儿等的时间短了(前面排的人少了)。 这是少见的【两个指标同时变好】的情形。条件是:活儿相互独立、数量远多于核数。 所以 Web 服务、批处理、渲染农场这些场景,多核几乎总是划算的。
二、单个大活儿:多核一点用都没有
一个 40 拍的活儿,核数 1/2/4,总耗时全是 40 拍。 因为一个进程只能在一个核上跑(除非它自己开线程拆任务)。 这条特别容易误解:很多人以为【机器有 8 核,我的程序就会快 8 倍】。不会。你的程序只用一个核。 所以【服务器 CPU 核多】不等于【你的单线程程序快】——单线程性能看的是单核频率与缓存,不是核数。
三、两头都好的前提
一、任务数 ≫ 核数。任务太少,多出来的核闲着(4.14 那个天花板)。 二、任务之间不共享。共享锁、共享内存、同一个文件,都会把并行变成排队。 三、瓶颈在 CPU。如果瓶颈在磁盘或网络,加核只是让它们抢得更凶。 这三条是【并行值不值得做】的判据,比任何框架选型都重要。
四、延迟与吞吐在多核下的关系
多核同时改善两者,只在【任务独立且数量多】时成立。 一旦有共享:吞吐可能上去,延迟反而变差——因为大家排队抢锁,每个人等的时间更长。 这就是【加机器反而更慢】的常见原因:共享点被抢爆了,机器越多抢得越凶。 判据:加机器之后如果 P99 延迟变差,先找共享点,别再加机器。
五、动手 Demo:吞吐量与延迟——多核也不是万能
两组对照:四十个小活儿(该随核数变快)与一个不可拆的大活儿(不该变)。 看第二张表那一列永远不变的 40。
# ① 四十个各 2 拍的活儿
for ncpu in (1, 2, 4):
ps = [Proc("T%d" % i, 2) for i in range(1, 41)]
done, sw, _tl, total = run(ps, quantum=1, ncpu=ncpu)
# ② 一个 40 拍的活儿
for ncpu in (1, 2, 4):
ps = [Proc("Big", 40)]
done, sw, _tl, total = run(ps, quantum=4, ncpu=ncpu)
实跑输出:
--------------------------------------------------------------------
吞吐量与延迟——多核也不是万能
--------------------------------------------------------------------
① 大批小活儿:核多确实快
核数 总耗时 平均周转 切换
--------------------------------------
1 80 60.5 79
2 40 30.5 78
4 20 15.5 76
② 单个大活儿:核再多也只能用一个
核数 跑完用
----------------
1 40
2 40
4 40
**一个不能拆的活儿,给它八个核也还是那么久。**
**所以【并行】的前提是【能拆】**——拆不开的,核数只是一堆闲着的硅。
第一张表:总耗时按核数下降,平均周转也跟着降。这是两个指标同时变好的少见情形,条件是任务独立且数量多。 第二张表:总耗时永远是 40 拍。一个进程只能在一个核上跑——这是【进程】这个抽象的最基本约束。 所以【机器有 8 核】不等于【你的程序快 8 倍】。单线程程序只用一个核,核多只是让别的程序不跟它抢。 加机器之后如果延迟反而变差,先找共享点(锁、同一块内存、同一个磁盘)。
30 秒实验
top里看一个单线程程序,CPU 列永远在 100% 附近,核再多也不涨。time一个多线程程序:user 时间超过 real 时间,才说明真用了多核。nproc与lscpu对比:逻辑核数往往是物理核的两倍(超线程),而超线程只提升一部分场景。
常见误区
- 【核多就一定快】。单线程程序只用一个核。核多的好处是【不跟别人抢】,不是【自己变快】。
- 【多核能让所有指标都变好】。有共享资源时,吞吐上去了、延迟反而变差。
- 【超线程等于两个核】。它是共享执行单元的,只提升一部分场景,重计算负载常常只能提升两三成。
自测三问(点开对答案)
1. 为什么一个 40 拍的活儿加核也不会变快? —— **一个进程只能在一个核上跑。**要变快必须自己开线程把任务拆开。 2. 多核什么时候能同时改善吞吐与延迟? —— 任务独立、数量远多于核数、瓶颈在 CPU。**有共享资源时就做不到了。** 3. 加机器之后延迟反而变差,先查什么? —— 查共享点:锁、同一块内存、同一个磁盘或网络。**共享点被抢爆了。**- ☐ 4.16 思考
相关笔记
- 实验结果 — 天花板在哪
- 思考 — 从加速比反推
- I/O调度器 — 瓶颈在 IO 时该看这一章
- 🐧 Linux是怎样工作的 · 索引