跳转至

面试题

https://mp.weixin.qq.com/s/imSLlhzNKXDeb_CRSoLWeA

好未来后端

单核CPU如何执行多个程序?

操作系统会为每个程序分配一个时间片,这个时间片是一个很短的时间间隔,例如几十毫秒。

单核 CPU 会轮流执行每个程序,在一个时间片内执行一个程序,当这个时间片用完后,就切换到下一个程序。这种方式给用户一种多个程序在同时运行的假象,因为切换速度非常快,用户难以察觉程序之间的切换。

CPU的流水线设计

一条指令的执行需要经过**取指令,翻译指令,执行指令**三个基本流程。CPU内部的电路也分为不同的单元:**取指单元、译码单元、执行单元**等,指令的执行也是按照流水线的工序一步一步执行的。如果采用流水线技术,则每个时钟周期内只有一个单元在工作,其余两个单元在“观望”

流水线设计将这些操作分成多个独立的阶段,每个阶段由专门的硬件单元负责,使不同指令的不同阶段可以并行执行,流水线的本质就是拿空间换时间。将每条指令的步骤分解到不同的电路单元,从而使得多个指令并行执行。

如果我们把一个指令拆分成“取指令 - 指令译码 - 执行指令”这样三个部分,那这就是一个三级的流水线。如果我们进一步把“执行指令”拆分成“ALU 计算(指令执行)- 内存访问 - 数据写回”,那么它就会变成一个五级的流水线。

尽管流水线无法减少单条指令执行时的 “延时” 这一性能指标,不过,借助于同时对多条指令的不同阶段展开执行,我们能够有效地提升 CPU 的 “吞吐率”。从外部视角来看,CPU 仿佛具备了 “一心多用” 的能力,在同一时刻,可以同时对 5 条不同指令的不同阶段进行处理。

CPU绑定的操作

在单核 CPU,虽然只能执行一个线程,但是操作系统给每个线程分配了一个时间片,时间片用完了,就调度下一个线程,于是各个线程就按时间片交替地占用 CPU,从宏观上看起来各个线程同时在执行。

而现代 CPU 都是多核心的,线程可能在不同 CPU 核心来回切换执行,这对 CPU Cache 不是有利的,虽然 L3 Cache 是多核心之间共享的,但是 L1 和 L2 Cache 都是每个核心独有的,如果一个线程在不同核心来回切换,各个核心的缓存命中率就会受到影响,相反如果线程都在同一个核心上执行,那么其数据的 L1 和 L2 Cache 的缓存命中率可以得到有效提高,缓存命中率高就意味着 CPU 可以减少访问 内存的频率。

当有多个同时执行「计算密集型」的线程,为了防止因为切换到不同的核心,而导致缓存命中率下降的问题,我们可以把**线程绑定在某一个 CPU 核心上**,这样性能可以得到非常可观的提升。

在 Linux 上提供了 sched_setaffinity 方法,来实现将线程绑定到某个 CPU 核心这一功能。