想象一家从深夜路边摊起家的餐厅。最早只有一个灶台,一道菜做完才能做下一道,客人多时只能干着急。后来老板把后厨扩建成四个灶台——这就是“多核”:在芯片上集成多个完整处理核心,让它们各做各的菜。再后来,有位老师傅练出了“分身术”:等水烧开的间隙切葱,等肉焖熟的工夫调汁,一个人也能把一口锅用到极致——这就是 SMT(同时多线程):让一个核心同时维护多个线程,把闲置的执行单元捡回来用。但灶台多了,麻烦也跟着来:四口锅共用一个冰箱,有人取走最后的鸡蛋,其他人必须立刻知道;订单像雪片一样飞来,主厨得让每个灶台都别闲着。本文就用这间后厨,把多核架构、SMT、缓存一致性、核间通信、调度与性能调优讲个明白。
对 AI 从业者而言,训练与推理服务动辄占用几十上百核,只有读懂多核并行与 SMT 的资源博弈,才能把每颗 CPU 的算力榨干、把云账单降下来,也能在“2 vCPU 到底等于几个核”这类规格问题上不被供应商绕晕。
可视化演示
展示多核处理器CMP架构、SMT同时多线程资源共享与缓存一致性协议,通过模式切换理解现代CPU并行架构的核心机制。
本节配有交互动效(进入视口后自动加载,约 3KB)。
多核处理器CMP架构 多核心通过片上互联总线通信 共享L3缓存降低延迟 负载均衡调度提升并行效率
多核架构设计
想象一家餐厅从小摊位扩大成后厨。老板没有把原有灶台“加大一号”——那要改造燃气管道、挑战物理极限——而是直接买来四套灶台并排摆开。这就是“多核”的朴素思路:与其让一个核心疯狂超频撞上功耗墙,不如在芯片上集成多个完整核心,让它们各做各的菜。每个核心都拥有自己的运算单元、寄存器堆和私有缓存,是真正意义上的“另一个厨师”。
但灶台摆好不是万事大吉。四口锅得共用一个水槽、一块案板、一台冰箱。在芯片世界里,这些“公共设施”就是共享的最后一级缓存(LLC)和内存控制器;而连接四个核心的“传菜通道”,则是片上互联网络。互联结构决定了厨师之间传话的快慢:总线像一条窄过道,所有人都挤在上面,简单但容易堵车;环形像环形轨道,相邻灶台传菜快,适合中量核心;网格像棋盘格的传菜机器人轨道,适合几十上百个核的大规模芯片。
核心的设计还有同构与异构之分。同构是四名同款厨师,能力一致、调度简单;异构则是“大厨 + 帮厨”的搭配(如 ARM 的 big.LITTLE),大核负责冲刺、小核负责日常琐事,省电又灵活。但要注意,核心数量不是想加就加:芯片面积、功耗墙、互联带宽都会约束扩展路径,这也是为什么服务器 CPU 的核数增长总是伴随着架构革新。
回到餐厅:多核架构设计就是决定灶台怎么摆、传菜通道怎么修、大厨小厨怎么搭配。而接下来你会发现,就算灶台摆好了,怎么让每位厨师“一心多用”,是另一门学问。
- 可并行比例 P整个任务中可以同时执行的部分占总工作量的比例。P 越接近 1,说明程序越适合多核并行。
- 串行比例 (1-P)必须按顺序执行的部分,比如读配置文件、汇总最终结果。这部分无法被多核“摊薄”。
- 并行部分的加速可并行部分被 N 个核心分摊后,耗时降为原来的 P/N。这就是加灶台带来的红利。
- 总体加速比 S串行耗时除以并行改造后的总耗时,得到整个程序的加速倍数。
SMT工作原理
后厨里有一位经验丰富的老厨师,面前只有一个灶台,但他从不闲着:水烧开前的两分钟,他已经切好了葱姜蒜;肉在锅里焖着的时候,他又去调好了酱汁。这种“利用等待时间穿插干活”的功夫,就是 SMT 的思想原型——在 CPU 的世界里,“等水开”对应的是流水线停顿,比如缓存未命中时,执行单元要干等几百个周期。
SMT 的做法是:让一个核心同时维护多套线程上下文——包括寄存器组、程序计数器、状态位——当一条线程被内存访问卡住时,立刻切换到另一条线程继续发射指令。这样原本空闲的执行单元(算术逻辑单元、访存单元等)就被“捡”了回来。从软件视角看,一个物理核心仿佛变成了多个“逻辑处理器”,这就是 Intel 超线程(Hyper-Threading)背后的原理。
硬件多线程按穿插粒度分为三种形态:粗粒度多线程,一条线程跑到停顿才整体切换,像厨师做完一道菜的等待期才去管另一口锅;细粒度多线程,每个周期都轮流发射不同线程的指令,像厨师每秒都在四口锅之间轮转;同时多线程(SMT)则更进一步,每个周期从多个线程中挑出“能执行”的指令,把执行单元的空闲槽填满,相当于厨师根据每口锅的状态灵活决定下一步摸哪个锅铲。
不过要泼一盆冷水:SMT 不是在“变出”新的执行单元,而是把原来闲置的等待时间捡了回来。所以它的加速比通常只有 15%~30%,远达不到线程数的倍数——相当于老厨师再分身,还是只有一口锅的火力。
- 硬件线程数 T一个核心同时维护的线程上下文个数。现代 CPU 通常每核 2 个,少数处理器做到 4 个或 8 个。
- 空闲资源比例 ρ单线程运行时,执行单元平均闲置的比例。CPU 密集且缓存友好的程序 ρ 很小,访存密集的程序 ρ 很大。
- 额外线程的增益第 2 到第 T 个线程总共能利用的闲置资源,近似为 (T-1)×ρ。
- 理论加速比 A基线程的 1 份能力,加上额外线程捡回来的部分,就是 SMT 的总收益。
SMT与CMP对比
老板现在面临两个方案:方案 A 是再雇一位厨师、多添一个灶台(CMP,多核);方案 B 是让现有厨师练分身术(SMT,同时多线程)。前者每多一个人都要多付一份工资、多占一块地皮;后者几乎不占额外空间,但一个人分身时,分身们必须共用同一双手、同一条胳膊。
从资源视角看,两种方案的本质差异在于“共享”与“独占”。CMP 为每个线程准备了一整套独立资源——完整的取指、译码、执行、缓存单元——所以性能随核数接近线性增长,但面积和功耗也线性上涨;SMT 只增加线程上下文(寄存器和状态位),几个线程共享同一套执行单元、缓存和内存带宽,面积开销极小(每个额外线程只多约 5%~15% 的芯片面积),但线程多了会互相抢资源,边际收益递减。
现实中两者不是二选一,而是组合:物理上集成多个核心(CMP),每个核心再用 SMT 维护多个硬件线程,构成“核数 × 每核线程数”的逻辑线程总数。例如 4 核 8 线程,就是 4 个完整执行单元、每个单元维护 2 套线程上下文。这正是现代服务器 CPU 的主流形态。
类比一下:最优解是“四个灶台,每位厨师再练一点分身术”。CMP 提供了并行度这辆车的四个轮子,SMT 则给每个轮子加了防滑纹,让空闲的路面也能借上力。
- CMP 总面积N 个独立核心,每个都包含完整执行单元与私有缓存,面积按核数线性累加。
- SMT 总面积一个核心的面积,加上 T 份线程上下文的小额开销,δ 是单份上下文的核心面积占比。
- 上下文占比 δ线程上下文只是寄存器堆加少量状态位,通常只占核心面积的 5%~15%。
缓存一致性
后厨里四位厨师共用一台冰箱,问题来了:王师傅打开冰箱发现鸡蛋只剩最后两个,全拿去做了蛋糕;正在做蛋炒饭的李师傅并不知道,还照着记忆里的“冰箱有蛋”下单。如果不解决,后厨就会乱套——而这正是多核系统每天要应对的挑战。
计算机里,每个核心都有私有的 L1/L2 缓存,多个核心共享同一片内存。同一个数据可能同时存在于多个核心的私有缓存中,一旦某个核心修改了它,其他核心缓存里的副本就过期了。硬件必须保证:任何一个核心读到的数据,都是全局最新的值。这个保证,就叫缓存一致性(Cache Coherence)。
经典的解决方案是 MESI 协议。每个缓存行处于四种状态之一:Modified(已修改)、Exclusive(独占)、Shared(共享)、Invalid(失效)。核心写数据前,要向其他核心广播“写失效”(Invalidate)消息,命令它们的副本作废;下次再读,必须重新从内存或其他核心获取最新值。核数少时广播便宜,核数多了就会形成广播风暴,于是出现目录协议——用一个集中目录记录“谁缓存了这份数据”,只通知相关核心,把广播从“喊给所有人听”变成“只喊给相关的人听”。
一致性协议的代价,就像后厨里每次有人动冰箱都要喊一嗓子“鸡蛋没啦”;人多时喊话本身就浪费精力。这也是为什么多核程序里要尽量减少共享数据的写操作,多用局部变量、减少锁的持有时间。
- 核心数 N参与共享数据的核心数量。N 越大,需要通知的“厨师”越多。
- 单条失效消息延迟 t_msg一条“你的缓存副本作废了”的消息从发起核心到达目标核心所需的时间。
- 总失效开销广播给所有核心的总时间。若用目录协议,则只需通知持有副本的核心,开销远小于 N 倍。
核间通信
灶台之间如何传话?一种方式是“约好位置放纸条”——所有厨师都知道调料台上有个固定便签栏,信息放上去,谁需要谁来取;另一种是“直接喊话”——王师傅对着隔壁灶台喊“酱油借我用一下”。这两种方式,对应多核通信的两大模型:共享内存与消息传递。
共享内存模型是目前多核 CPU 的主流:所有核心通过片上互联访问同一物理内存,配合原子操作与同步原语(如 compare-and-swap、fetch-and-add)来保证并发安全。它的优点是程序员心智负担小,缺点是同步开销和一致性流量不可忽视。消息传递模型则通过显式的发送/接收接口通信,线程之间不共享数据,天然避免了竞争,常见于分布式系统,部分众核芯片也在硬件层面提供消息传递支持。
通信的物理基础是片上互联拓扑。总线把所有核心挂到一条共享通道上,简单但带宽有限,适合 4 核以内的场景;环形拓扑让数据沿环传递,相邻节点延迟低,适合 8~16 核;网格(Mesh)把核心排成二维阵列,每个节点只和邻居直连,适合几十上百核的大规模芯片。无论哪种拓扑,一次通信的延迟都可以拆成两部分:无论消息多短都要付的“起步价”,以及随数据长度线性增长的传输时间。
回到后厨:如果传菜通道设计得好(拓扑合理)、喊话内容精炼(消息短)、对讲机开机快(启动开销小),那么 8 个灶台协作起来依然井井有条。反之,通道拥堵会让“多核”变成“多等你”。
- 启动开销 α建立一次通信的固定成本,包括握手、路由决策、同步开销,与消息大小无关。
- 每字节传输时间 β在互联通道上传输一个字节的平均时间,由带宽决定。
- 消息长度 L要传输的数据量,单位通常是字节。
- 总通信延迟起步价与里程费之和。频繁的小消息通信,α 占主导,应尽量合并成更大的消息。
多核调度
餐厅里订单如雪片般飞来,主厨(操作系统)的责任是:让每个灶台都别闲着,也别让某个灶台忙到冒烟。这份“派单”的工作,就是多核调度。
调度器的主要目标有三个。第一是负载均衡:把就绪线程均匀分配到各核,避免“旱的旱死、涝的涝死”。第二是线程亲和性:尽量让一个线程在原来的核上继续运行,因为它的私有缓存里还“热乎”着,换核等于把缓存全部清零。第三是控制任务迁移:线程从一个核搬到另一个核,代价是缓存全凉、TLB 失效,迁移太频繁反而亏本——所以调度器宁愿让负载略有不均,也不愿频繁“搬菜”。
现代调度器(如 Linux 的 CFS)通过周期性负载均衡、按调度域(sched domain)分级迁移、以及唤醒时优先选择最近空闲核的倾斜策略来平衡这些目标。衡量均衡程度的一个朴素方法,是计算各核负载的均方差:方差越小,说明分配越均匀。实际系统中还会结合 NUMA 感知——优先把线程调度到离它内存更近的核上,避免跨 socket 访问内存带来的长延迟。
主厨的智慧在于“微调优于折腾”:与其不断把菜搬来搬去,不如让每道菜在同一个灶台上做完。绑核(CPU Pinning)之所以能提升性能,正是利用了这种“缓存热度”——这也是容器和虚拟机平台做性能调优时最常用的手段之一。
- 核心数 N参与调度的物理核心数量。
- 第 i 个核的负载 L_i每个核心当前的就绪线程数或运行队列长度。
- 平均负载 L̄所有核心负载的平均值,是均衡的理想基准。
- 均方差 σ各核负载偏离平均水平的程度。σ 趋近于 0,表示负载完全均衡。
性能分析
老板最终关心的只有两件事:一天能出多少道菜(吞吐量),以及客人下单后多久能吃上(延迟)。多核与 SMT 的一切设计,最终都要用这两个指标说话。
多核能近乎线性地提升吞吐量,前提是任务可并行;而延迟——单道菜的上菜时间——往往不会因为多核而变快,甚至因为排队、同步和一致性开销而略有上升。性能分析里用加速比和并行效率刻画这种规律:效率 = 加速比 ÷ 核数。核数越多、串行比例越大,效率越低,因为多核带来的收益被串行部分的“隐形税”不断稀释。
实际数据可以参考:4 核相比单核,完全可并行的负载吞吐量接近 4 倍;但加入 10% 串行部分后,加速比只有约 3.1 倍;超线程(每核 2 线程)的额外增益通常在 15%~30% 之间,内存带宽、锁竞争、调度开销还会进一步压低收益。所以“堆核数”不是万能药,算法先行、减少串行瓶颈,才是提升多核收益的根本。
- 可并行比例 P与 Amdahl 定律中的 P 相同,指可并行部分占比。
- 核数 N 放大串行代价串行部分虽然只有 (1-P),但每个核都在等它,整体代价被放大为 (1-P)×N。
- 总时间模型并行时间 P 与串行代价之和,构成 N 核下的总执行时间。
- 并行效率 E加速比除以核数,衡量每个核的“出菜效率”。E=1 是完美线性,现实中总是小于 1。
实践应用
当餐厅生意好到可以接包场时,老板发现一个灶台可以分时段租给不同团队——这是虚拟化;后来又出现一种更轻的方式——让一支小团队直接共用同一套灶具的不同区域——这是容器化。在多核与 SMT 的世界里,它们对应虚拟机与容器对 CPU 资源的两种划分方式。
在虚拟化场景中,云厂商把物理线程包装成 vCPU 卖给用户。一台“4 核 8 线程”的物理机可以拆出 8 个 vCPU;但要注意,2 个 vCPU 若落在同一物理核的两个 SMT 线程上,性能远达不到 2 个完整核——这正是云主机规格文档里"2 vCPU"背后可能隐藏的陷阱。容器化场景则轻量得多:容器共享宿主机内核,靠 cgroup 的 CPU 配额(quota)和 CFS 调度器进行线程级分配,隔离粒度更细、密度更高。
实际调优中,CPU 密集型的数据库和高性能计算往往建议关闭或绕过 SMT(独占整个物理核),而虚拟机/容器混部场景则乐于开启超线程以提高资源利用率。绑定 NUMA 节点、避免跨 socket 访问内存,也是多核调优的常见手段。至此你会发现:多核与 SMT 的所有设计,最终都服务于“把资源用满、把冲突降到最低”这一目标——理解了后厨的灶台布局与协作规则,再看任何一台服务器的 CPU 规格,你都能一眼看懂它背后的权衡。
- 物理核数 C 与每核线程数 T物理核数乘以每核硬件线程数,得到物理线程总数。
- vCPU 需求总和所有虚拟机申请的虚拟 CPU 数量之和。
- 超分比 O两者之比。O 越大,资源利用率越高,但性能隔离越差;CPU 密集型负载通常要求 O 接近 1。
AI 应用场景
云厂商 vCPU 规格设计与售卖
阶段:系统架构与资源规划
解决的问题:传统物理机按整核售卖,资源碎片化严重;AI 训练与推理集群需要弹性算力,但用户常误解“vCPU 数量 = 物理核数量”。云厂商基于多核与 SMT 把物理线程包装成 vCPU,通过超分比在“多卖资源”与“性能隔离”之间权衡——就像后厨把同一个灶台分时段租给不同团队,但要保证谁都不会饿肚子。
具体案例:某云厂商的实例规格标注"2 vCPU",实际对应 1 个物理核的 2 个 SMT 线程;文档明确提醒:CPU 密集型任务建议选择独占核的规格,避免与隔壁虚机争抢执行单元,而突发型网页服务选择 SMT 规格则能显著降低成本。
容器平台 CPU 限额与绑核
阶段:部署与性能调优
解决的问题:容器默认共享宿主机所有核,多个容器可能挤在同一物理核上互相拖慢,还会因为频繁迁移丢失缓存热度。通过 cpuset 绑核与 CPU quota 设置,让 AI 推理服务独占若干物理核,避免 SMT 竞争与缓存抖动——相当于给每支厨师小队划好固定的灶台,不许乱窜。
具体案例:在 Kubernetes 中为推理服务配置 Guaranteed QoS,并用静态 CPU Manager 把容器钉在专属核上;同时把“核数 × 每核线程数”换算清楚,避免 8 个逻辑线程被错误地塞进 4 个物理核,导致延迟翻倍。
AI 推理服务的线程数调优
阶段:模型部署与推理优化
解决的问题:CPU 推理引擎(如 OpenMP、oneDNN)默认线程数常等于逻辑线程数,导致同一物理核上的 SMT 线程互相争抢执行单元,吞吐反而下降。正确做法是按物理核数设置线程数,并开启绑核——就像后厨明明只有四个灶台,却给厨师排了八个岗位,结果大家都在抢锅铲。
具体案例:某 LLM 推理服务在 32 核 64 线程的机器上,把 OMP_NUM_THREADS 从 64 调到 32 并绑定 NUMA 节点后,单请求延迟降低 18%,吞吐量提升 12%,CPU 使用率曲线也平稳了许多。
Python 演示
import timefrom concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor def cpu_work(n=8000000): """模拟一条 CPU 密集的并行任务:累加平方和。""" total = 0 for i in range(n): total += i * i return total def measure(factory, workers, batches=4): t0 = time.perf_counter() args = [8000000] * batches with factory(max_workers=workers) as pool: list(pool.map(cpu_work, args)) return time.perf_counter() - t0 def main(): single = measure(ThreadPoolExecutor, 1) thread4 = measure(ThreadPoolExecutor, 4) process4 = measure(ProcessPoolExecutor, 4) print(f"单线程基线(单核单任务) : {single:.2f}s") print(f"4 线程(模拟SMT共享执行单元) : {thread4:.2f}s 加速比 {single / thread4:.2f}x") print(f"4 进程(模拟多核真并行) : {process4:.2f}s 加速比 {single / process4:.2f}x") if __name__ == "__main__": main()
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor引入“线程厨师团队”和“进程厨师团队”两种并行工具。def cpu_work(n=8000000):定义一条 CPU 密集型任务,模拟后厨里一道占满灶台的硬菜。with factory(max_workers=workers) as pool:按指定人数开一个工人池,相当于同时启用多个灶台。list(pool.map(cpu_work, args))把 4 份菜谱分给池里的工人并行执行,并收集结果。ThreadPoolExecutor(4)4 个线程在同一个进程内抢同一个解释器(GIL),类似 SMT:执行单元只有一个,线程多了反而互相“抢锅铲”。ProcessPoolExecutor(4)4 个进程各自独立解释器,类似 CMP:4 个完整核心各干各的,互不干扰。time.perf_counter()高精度计时器,用来量出每轮“出菜”的总耗时。
常见误区
误区我以为 4 核就是单核的 4 倍快,8 核就是 8 倍,买 CPU 只看核数就够了。反正核多不怕事。
正解Amdahl 定律早就告诉我们,串行比例决定了加速比上限。假设程序有 20% 必须串行,哪怕用 100 个核,加速比也到不了 5 倍。更别说内存带宽、锁竞争、调度开销都会进一步压低收益。就像后厨加了十个灶台,但传菜通道只有一条,菜全堵在过道上。
为何常见:厂商宣传和跑分软件都爱展示“多核全开”的理想场景,让人误以为核数直接等于性能;实际业务负载往往没那么“听话”。
误区任务管理器里看到 8 个框,我就以为这台机器有 8 个物理核心,可以放心开 8 个重量级任务。
正解4 核 8 线程指的是 4 个物理核心,每个核心通过 SMT 维护 2 个逻辑线程。逻辑线程共享同一套执行单元、缓存和带宽,两个“线程”同时跑满时是在抢同一口锅的火力。SMT 的实际增益通常只有 15%~30%,所以 8 线程不等于 8 核。
为何常见:操作系统和任务管理器默认显示逻辑处理器数量,用户看到几个框就以为是几个核,厂商也乐于用“8 线程”这种数字营销。
误区只要把程序改成多线程,性能就会变好;线程开得越多越好,反正 CPU 那么多核。
正解多线程有成本:创建线程要开销,线程间同步要加锁,共享数据会触发缓存一致性流量,任务迁移会丢失缓存热度。如果任务本身串行依赖强、临界区长,多线程反而更慢。就像后厨只有一道菜要出,派五个厨师反而互相碍手碍脚。
为何常见:教程里展示的多线程示例都是“可并行任务”,让人误以为并发等于免费午餐;实际业务中串行依赖和共享状态无处不在。
误区MESI 协议是 CPU 自动处理的,我写代码时不用关心缓存,反正硬件会保证正确。
正解硬件只保证“正确”,不保证“高效”。两个线程操作不同变量,但变量恰好落在同一条缓存行上,任何一方写入都会导致对方的缓存行失效,引发反复的一致性流量——这就是伪共享(False Sharing)。多核程序的性能杀手往往是这种看不见的缓存行争抢,需要程序员通过对齐填充、减少共享写来规避。
为何常见:一致性协议确实全自动运行,但“正确”和“高效”是两回事;性能问题比正确性问题隐蔽得多,不容易在测试阶段暴露。
面试题
Q1. 多核处理器提升性能的主要途径是什么?
- A.提高单个核心的主频
- B.同时执行多个独立任务← 正确答案
- C.增大缓存容量一倍
- D.减少指令集复杂度
答案:B。多核通过集成多个物理核心并行执行任务来提升吞吐量,相当于后厨多请几位厨师。提高主频会撞上功耗墙,增大缓存和精简指令集都不是多核的本质。
Q2. SMT(同时多线程)的核心思想是什么?
- A.增加物理核心数量
- B.提高单线程主频
- C.让一个核心同时维护多个线程上下文← 正确答案
- D.用软件模拟多台计算机
答案:C。SMT 在单个核心内维护多套线程上下文,利用执行单元的空闲时间穿插执行多个线程。这就像一位厨师在等水烧开时切菜,而不是再多雇一位厨师。
Q3. 某 CPU 标注为“4 核 8 线程”,这里的 8 线程指的是什么?
- A.8 个物理核心
- B.操作系统最多只能创建 8 个进程
- C.每核支持 2 个硬件线程(SMT)← 正确答案
- D.8 个独立的内存控制器
答案:C。4 核 8 线程 = 4 个物理核心 × 每核 2 个硬件线程。物理核仍是 4 个,逻辑线程共享执行单元,性能增益约 15%~30%,绝不是 8 个完整核的算力。
Q4. MESI 一致性协议要解决的核心问题是什么?
- A.多核间的电源管理
- B.提高指令流水线深度
- C.管理线程在核间的迁移
- D.多个核心私有缓存中的数据副本保持一致← 正确答案
答案:D。MESI 用 Modified/Exclusive/Shared/Invalid 四种状态管理缓存行,通过写失效广播保证各核心私有缓存中的副本一致——就像后厨共用的冰箱,有人取走最后的鸡蛋,其他厨师必须立刻知道。
Q5. 以下哪些属于多核调度器关注的重点?
- A.负载均衡,避免部分核心空转← 正确答案
- B.线程亲和性,减少迁移开销← 正确答案
- C.任务迁移时的缓存失效率← 正确答案
- D.提高单核主频
答案:ABC。调度器要让各核负载均匀(A),把常驻线程“粘”在原来的核上利用缓存热度(B),并控制迁移带来的缓存失效成本(C)。提高主频是硬件设计问题,不是调度器职责。
Q6. 根据 Amdahl 定律,当串行比例为 20% 时,用无限多个核心加速,理论加速比的极限是多少?
- A.2 倍
- B.5 倍← 正确答案
- C.10 倍
- D.无限大
答案:B。S = 1/((1-P)+P/N),当 N→∞ 时 S→1/(1-P)=1/0.2=5。串行部分是永远省不掉的瓶颈——餐厅里那 20% 必须按顺序走的流程,再多厨师也改不了。
Q7. 关于伪共享(False Sharing),下列说法正确的是?
- A.两个线程访问同一个变量导致竞争
- B.不同线程访问同一缓存行上的不同变量,引发频繁的缓存行失效← 正确答案
- C.缓存容量不足导致频繁换出
- D.多个核心共享最后一级缓存
答案:B。伪共享指两个线程操作不同变量,但这两个变量恰好落在同一条缓存行里,任何一方写入都会让对方副本失效,触发反复的一致性流量。好比两位厨师一个用酱油一个用醋,但两瓶调料放在同一个托盘上,一人动一下托盘就得整盘重摆。
Q8. 关于 SMT 与 CMP(多核)的组合应用,下列说法正确的有?
- A.CMP 提供并行度,SMT 填补每个核的空闲资源← 正确答案
- B.每核线程数越多,性能一定线性增长
- C.组合后逻辑线程总数为“核数 × 每核线程数”← 正确答案
- D.SMT 线程之间会竞争执行单元、缓存和带宽← 正确答案
答案:ACD。CMP 增加并行度(A),SMT 利用核内空闲资源,但线程间也共享执行单元、缓存和带宽,存在竞争(D)。组合后的逻辑线程数是核数乘每核线程数(C)。SMT 增益受资源竞争限制,不会线性增长(B 错)。
Q9. 在虚拟化环境中,云主机规格"2 vCPU"最可能对应下面哪种映射?
- A.始终对应两个完整物理核
- B.可能映射到同一物理核的两个 SMT 线程← 正确答案
- C.必然独占一个物理核的所有线程
- D.与物理资源完全无关的纯软件概念
答案:B。vCPU 本质是物理线程的抽象,2 个 vCPU 很可能落在同一物理核的两个 SMT 线程上,性能远低于 2 个完整核。这就是为什么 CPU 密集型任务要选“独占核”规格。
Q10. 以下哪些做法能提升多核系统的实际吞吐量?
- A.减少串行临界区,增大可并行比例← 正确答案
- B.让线程绑核运行,利用缓存局部性← 正确答案
- C.让多个线程并发写同一缓存行以减少一致性开销
- D.结合 SMT 与多核,合理分配逻辑线程← 正确答案
答案:ABD。增大可并行比例(A)、绑核提升缓存命中(B)、合理组合 SMT 与多核(D)都能提升吞吐。C 恰恰相反,多线程写同一缓存行会引发伪共享和一致性风暴,是典型的性能杀手。