1.前言
CPU 推动了所有软件的运行,因而通常是系统性能分析的首要目标。现代系统一般有多颗CPU,通过内核调度器共享给所有运行软件。当需求的CPU 资源超过了系统力所能及的范围时,进程里的线程(或者任务)将会排队,等待轮候自己运行的机会。等待给应用程序的运行带来严重延时,使得性能下降。

2.模型
图展示了一个CPU 架构的示例,单个处理器内共有四个核和八个硬件线程。硬件线程是一种支持在一个核上同时执行多个线程(包括Intel 的超线程技术)的CPU架构,每个线程是一个独立的CPU 实例。这种扩展的方法又称为多线程。

为了提高内存I/O 性能,处理器提供了多种硬件缓存。图展示了缓存大小的关系,越小则速度越快(一种权衡),并且越靠近CPU。

图展示了一个由内核调度器管理的CPU 运行队列。

正在排队和就绪运行的软件线程数量是一个很重要的性能指标,表示了CPU 的饱和度。在上图中(在这一瞬间)有四个排队线程,加上一个正在CPU 上运行的线程。花在等待CPU 运行上的时间又被称为运行队列延时或者分发器队列延时。
3.CPU运行
时钟是一个驱动所有处理器逻辑的数字信号。每个CPU 指令都可能会花费一个或者多个时钟周期(称为CPU 周期)来执行。CPU 以一个特定的时钟频率执行,例如,一个5GHz 的CPU每秒运行五十亿个时钟周期。
CPU 执行指令集中的指令。一个指令包括以下步骤,每个都由CPU 的一个叫作功能单元的组件处理:
- 1.指令预取
- 2.指令解码
- 3.执行
- 4.内存访问
- 5.寄存器写回
最后两步是可选的,取决于指令本身。许多指令仅仅操作寄存器,并不需要访问内存。
CPU 花在执行用户态应用程序代码的时间称为用户时间,而执行内核态代码的时间称为内核时间。内核时间包括系统调用、内核线程和中断的时间。
大多数处理器都以某种形式提供多个CPU。对于一个64 颗CPU 的系统来说,这意味着一个应用程序如果同时用满所有CPU,可以达到最快64 倍的速度,或者处理64 倍的负载。应用程序可以根据CPU 数目进行有效放大的能力又称为扩展性。

不管使用何种技术,重要的是要创建足够的进程或者线程,以占据预期数量的CPU。如果要最大化性能,即所有的CPU。

4.CPU硬件
CPU 硬件包括了处理器和它的子系统,以及多处理器之间的CPU 互联。

图展示了一个普通处理器是如何访问不同级别缓存的。

MMU 负责虚拟地址到物理地址的转换。图展示了一个普通的MMU,附有CPU 缓存类型。

5.CPU软件
支撑CPU 的内核软件包括了调度器、调度器类和空闲线程。

● 分时:可运行线程之间的多任务,优先执行最高优先级任务。
● 抢占:一旦有高优先级线程变为可运行状态,调度器能够抢占当前运行的线程,这样较高优先级的线程可以马上开始运行。
● 负载均衡:把可运行的线程移到空闲或者较不繁忙的CPU 队列中。
对于Linux 内核,调度器类如下。
● RT:为实时类负载提供固定的高优先级。内核支持用户和内核级别的抢占,允许RT任务以短延时分发。优先级范围为0~99(MAX_RT_PRIO-1)。
● O(1):O(1)调度器在Linux 2.6 作为默认用户进程分时调度器引入。名字来源于算法复杂度O(1)(大O 表示法的介绍参见第5章)。先前的调度器包含了一个遍历所有任务的函数,算法复杂度为O(n),这样扩展性就成了问题。相对于CPU 消耗型线程,O(1)调度器动态地提高I/O 消耗型线程的优先级,以降低交互和I/O 负载的延时。
● CFS:Linux 2.6.23 引入了完全公平调度作为默认用户进程分时调度器。这个调度器使用红黑树取代了传统运行队列来管理任务,以任务的CPU 时间作为键值。这样使得CPU 的少量消费者相对于CPU 消耗型负载更容易被找到,提高了交互和I/O 消耗型负载的性能。
NUMA 系统上的性能可以通过使内核感知NUMA 而得到极大提高,因为这样它可以做出更好的调度和内存分配决定。它可以自动检测并创建本地化的CPU 和内存资源组,并按照反映NUMA 架构的拓扑结构组织起来。这种结构可以预估任意的内存访问开销。


参与讨论

本文探讨了CPU在系统性能中的核心作用,特别是在多核处理器环境中。内容涵盖CPU架构、硬件线程、缓存层次、内核调度器的工作原理,以及CPU运行和硬件细节。重点讨论了运行队列延迟、负载均衡和扩展性,强调了正确利用CPU资源以提升系统性能的重要性。同时,还介绍了CPU软件层面,如调度器的分时、抢占和负载均衡策略,以及针对NUMA系统的优化。

904

被折叠的 条评论
为什么被折叠?



