CPU

平均负载

Load Average,简单理解它是指单位时间内,系统处于__可运行状态__和__不可中断状态__的平均进程数,即__平均活跃进程数__。因此理论上最理想情况是逻辑 CPU 核心数量

  • 可运行状态进程:正在使用 CPU 或者正在等待 CPU 的进程,即 R 状态
  • 不可中断状态进程:正处于内核态关键流程中的进程,这些流程是不可打断的,如等待磁盘 IO,即 D 状态

简单举例如下:

CPU 密集型进程,CPU 使用率 与 平均负载 都会升高
I/O 密集型进程,等待 I/O 导致平均负载升高,CPU 使用率不一定很高
大量等待 CPU 调度的进程,平均负载 与 CPU 使用率 都会升高

使用率

  • usr CPU 使用率:CPU 在用户态运行的时间百分比,usr CPU 使用率高说明有应用程序比较繁忙
  • sys CPU 使用率:CPU 在内核态运行的时间百分比(不包括中断)
  • wait IO CPU 使用率:CPU 在等待 IO 的时间百分比,iowait高通常说明系统与硬件设备的 IO 交互时间较长
  • 硬中断、软中断 CPU 使用率:内核调用硬中断、软中断处理程序的时间百分比
  • 虚拟化环境中会用到的窃取 CPU 使用率(steal)和客户 CPU 使用率(guest),分别表示被其他虚拟机占用的 CPU 时间百分比,和运行客户虚拟机的 CPU 时间百分比

CPU 上下文切换

每个任务运行前,CPU 都需要知道任务从哪里加载和运行,即需要系统帮它设置好 CPU 寄存器和程序计数器(PC),它们都是 CPU 在运行任何任务前必须依赖的环境,因此也被叫做 CPU 上下文

CPU 上下文切换即先把前一个任务的 CPU 上下文保存起来(在内核中),然后加载新任务的上下文,最后跳转到程序计数器所指的新位置,运行新任务。切换操作同样要运行在 CPU 上(sys CPU)

  • 特权模式切换:进程通过调用系统调用完成从用户态切换到内核态的运行,首先保存用户态 CPU 上下文,然后加载内核态 CPU 上下文,最后跳转到内核态运行内核任务;系统调用结束后,首先恢复原来保存的上下文,然后跳转到用户态,继续运行

  • 进程上下文切换:进程是由内核管理和调度的,进程的切换只能发生在内核态)。进程的上下文不仅包括内核堆栈、寄存器等内核空间的状态,还包括虚拟内存、栈、全局变量等用户空间的资源

    • 性能问题:
      - 切换带来的一系列操作占用 CPU
      - 虚拟内存更新后,TLB(虚拟内存到物理内存的映射缓存)被刷新,内存访问变慢
    • 切换时机:
      - 公平调度
      - 系统资源不足,挂起需要资源的进程
      - 进程主动挂起自身,如调用sleep
      - 发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序(不涉及进程用户态资源的保存与恢复)
  • 线程上下文切换:线程是调度的基本单位,而进程则是资源拥有的基本单位。内核中的任务调度的对象是线程。同一进程内线程的上下文切换包括了线程的私有数据、栈、寄存器等,虚拟内存和全局变量等资源是不需要保存与恢复的

  • 中断上下文切换:对同一个 CPU 来说,中断处理比进程拥有更高的优先级。如上所述会引起进程上下文切换

进程状态

  • R,Running or Runnable
  • D,Dist Sleep,Uninterruptible Sleep
  • Z,Zombie
  • S,Interruptible Sleep
  • I,Idle
  • T/t,Stopped or Traced,暂时或追踪
  • s,一个会话的领导进程
    • 会话:指共享同一个控制终端的一个中多个进程组,如打开一个控制终端(TTY)就对应一个会话
  • +,表示前台进程组
    • 进程组:一组相关联的进程,如每个子进程都是父进程所在组的成员

软中断

Linux 将中断处理过程分两部分,第一部分快速处理中断,它在中断禁止模式下运行(打断 CPU 正在执行的任务,立即执行中断处理程序),主要处理跟硬件紧密相关的或时间敏感的工作,即硬中断;第二部分用来延迟处理上半部未完成的工作,即软中断,通常以内核线程的方式运行(由内核触发),每个 CPU 都对应一个软中断内核线程,名字是 ksoftirqd/CPU编号。发软中断事件频率过高时,内核线程也会因为 CPU 使用率过高而导致软中断处理不及时,进而引发网络收发延迟、调度缓慢等性能问题

例如在第一部分把网卡数据读到内存中,然后更新硬件寄存器状态表示数据读取完成,最后发送一个软中断信号;在第二部分接收到软中断信号并被唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序

性能分析相关命令

  • top/uptime:可以观察当前平均负载情况

    • %iowait,等待 IO 的 CPU 时间百分比
    • top -H -p PID 可查看PID下的线程
  • htop:top增强版

  • atop:CPU、内存、磁盘和网络等各种资源的全面监控

  • mpstat:实时查看每个 CPU 的性能指标以及所有 CPU 的平均指标

  • pidstat:实时查看进程的 CPU、内存、IO 以及上下文切换等性能指标

    • pidstat -u CPU指标
    • pidstat -d 展示统计数据
    • pidstat -wt -u -p PID 1:查看某个进程的线程上下文切换情况
      • cswch, voluntary context switches,每秒自愿上下文切换次数,指进程无法获取所需资源导致的上下文切换
      • nvcswch, non voluntary context switches,每秒非自愿上下文切换次数,指进程由于时间片已到等原因,被系统强制调度而发生的上下文切换
      • %wait,进程等待 CPU 的时间百分比
  • dstat:可以同时查看 CPU 和 I/O 两种资源的使用情况

  • pstree

  • vmstat:主要用来分析系统的内存使用情况,也常用来分析 CPU 总体上下文切换的中断的次数

    • cs, context switch,每秒上下文切换次数,总体上下文切换情况
    • in, interrrupt,每秒中断次数
    • r, Running or Runnable,就绪队列长度
    • b, Blocked,不可中断睡眠状态进程数
  • perf

    • perf top -g -p PID:查找热点函数,实时显示占用 CPU 时钟最多的函数或指令
    • perf record -e cpu-clock -g -p {PID}:采样
    • perf report -i perf.data:解析perf.data,但不是很直观
    • git clone https://github.com/brendangregg/FlameGraph.git
    • perf script -i perf.data &> data.unfold:解析perf.data
    • ./FlameGraph/stackcollapse-perf.pl data.unfold &> data.fold
    • ./FlameGraph/flamegraph.pl data.fold > data.svg:查看火焰图
  • /proc/softirqs 软中断运行情况(系统运行以来的累积次数)

    • watch -d cat ...
  • /proc/interrupts 硬中断运行情况

  • sar:系统活动报告工具,实时查看系统当前活动,也可以配置保存和报告历史统计数据

    • sar -n DEV 1,显示网络收发报告
      • rxpck/s、txpck/s 表示每秒接收、发送网络帧数,即 PPS
      • rxkB/s、txKB/s 表示每秒接收、发送kB数,即 BPS
  • 参考

性能测试相关工具

待补充

内存

生产环境性能问题分析

tbb concurrent queue 的无限循环导致 CPU 使用瞬间打满

重构后的 本地缓存 使用 CPU 过高

CPU 的上下文切换,调整合适的线程数量

usleep 3 并不准确

程序性能测试工具

程序处理请求过程中,根据监控发现latency会产生周期性的峰值。因此尝试了多种性能测试工具,记录如下。

vmstat

查看缺页中断

查看进程运行在哪些CPU内核上

查看内存泄露

strace

pstack pid

  • 查看线程栈

  • 分析死锁原因

    • 使用pstack可以打印出各线程栈信息,基本上可以确定哪些线程在block状态
    • gdb attach pid
      • info thread
        • 打印所有线程信息
      • thread pid
        • 切换到block住的thread
      • p pthread_mutex_
        • 查看互斥锁的__owner是哪个线程
  • 参考

gprof

posted on 2019-02-17 15:42  chenguang9239  阅读(600)  评论(0编辑  收藏  举报