Linux性能优化

CPU

系统层面的一些优化手段:

一些分析诊断工具

平均负载

平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,和 CPU 使用率并没有直接关系

在只有 2 个 CPU 的系统上,平均负载为 2 代表所有的 CPU 都刚好被完全占用,大量 IO 会导致平均负载变高,但 CPU 使用率却不一定高

top 命令展示的三个值,分别为 1 分钟、5 分钟、15 分钟内的平均负载

上下文切换

vmstat 可以查看系统整体上下文切换情况:

pidstat 则可以查看单个进程的上下文切换情况,cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数,另一个则是 nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数

中断处理也需要上下文切换,可以通过 /proc/interrupts 查看中断最多的类型

CPU使用率

通过 top 可以查看 CPU 在不同场景下的运行时间:

为了在具体进程找到占用 CPU 时钟最多的函数或者指令,可以通过 perf top 查看函数名或函数地址

软中断

Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:

网卡接收到数据包后,会通过硬件中断的方式通知内核有新的数据到了 对上半部来说,既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个软中断信号,通知下半部做进一步的处理 下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序

上半部会打断 CPU 正在执行的任务,然后立即执行中断处理程序。而下半部以内核线程的方式执行,并且每个 CPU 都对应一个软中断内核线程,名字为 “ksoftirqd/CPU 编号”

当软中断事件的频率过高时,内核线程也会因为 CPU 使用率过高而导致软中断处理不及时,进而引发网络收发延迟、调度缓慢等性能问题

内存

通过 free 可以查看整体内存使用情况:

通过 top 查看具体进程的内存情况:

分配与回收

malloc()

对小块内存(小于 128K),C 标准库使用 brk() 来分配,也就是通过移动堆顶的位置来分配内存。这些内存释放后并不会立刻归还系统,而是被缓存起来,这样就可以重复使用,brk() 方式的缓存,可以减少缺页异常的发生,提高内存访问效率

而大块内存(大于 128K),则直接使用内存映射 mmap() 来分配,也就是在文件映射段找一块空闲内存分配出去

当进程通过 malloc() 申请内存后,内存并不会立即分配,而是在首次访问时,才通过缺页异常陷入内核中分配内存

buff/cache

buff 是对磁盘读写数据的缓存,而 cache 是对文件读写数据的缓存

在读写普通文件时,会经过文件系统,由文件系统负责与磁盘交互;而读写磁盘或者分区时,就会跳过文件系统,也就是所谓的裸I/O

swap

swap 是一种虚拟内存交换到磁盘的机制

有一个专门的内核线程用来定期回收内存,也就是 kswapd0

kswapd0 定义了三个内存阈值:页最小阈值(pages_min)、页低阈值(pages_low)和页高阈值(pages_high)

NUMA 下,多个处理器被划分到不同 Node 上,且每个 Node 都拥有自己的本地内存空间,每个 Node 会有自己的 swap

Linux 提供了一个 /proc/sys/vm/swappiness 选项,用来调整使用 Swap 的积极程度:swappiness 的范围是 0-100,数值越大,越积极使用 Swap,也就是更倾向于回收匿名页;数值越小,越消极使用 Swap,也就是更倾向于回收文件页