Linux 系统的性能测试与性能分析

恒温 · 2012年11月30日 · 1348 次阅读

Link http://www.ltesting.net/ceshi/ceshijishu/xncs/2012/1130/205763.html

  Revision History

Version

Date

Author

Description

1.0

2011/5/26

dengwu@taobao.com

初稿

1.1

2011/6/23

dengwu@taobao.com

添加 CPU 分析

1.2

2012/2/20

dengwu@taobao.com

添加 MEM,IO 分析

1.3

2012/2/23

dengwu@taobao.com

更新工作原理

1.4

2012/2/25

dengwu@taobao.com

添加中断分析

1.5

2012/2/28

dengwu@taobao.com

添加网络分析

  1 性能测试简介

  性能测试的过程就是找到系统瓶颈的过程。

  性能测试 (包括分析和调优) 的过程就是在操作系统的各个子系统之间取得平衡的过程。

  操作系统的各个子系统包括:

  CPU

  Memory

  IO

  Network

  他们之间高度依赖,互相影响。比如:

  1. 频繁的磁盘读写会增加对内存的使用

  2. 大量的网络吞吐,一定意味着非常可观的 CPU 利用率

  可用内存的减少可能增加大量的 swapping,从而使系统负载上升甚至崩溃

  2 应用程序类型

  性能测试之前,你首先需要判断你的应用程序是属于那种类型的,这可以帮助你判断哪个子系统可能会成为瓶颈。

  通常可分为如下两种:

  CPU bound – 这类程序,cpu 往往会处于很高的负载,当系统压力上升时,相对于磁盘和内存,往往 CPU 会首先到达瓶颈。Web server,mail server 以及大部分服务类程序都属于这一类。

  I/O bound – 这类程序,往往会频繁的访问磁盘,从而发送大量的 IO 请求。IO 类应用程序往往利用 cpu 发送 IO 请求之后,便进入 sleep 状态,从而造成很高的 IOWAIT。数据库类程序,cache 服务器往往属于这种类型。

  3 CPU

  3.1 性能瓶颈

  3.1.1 运算性能瓶颈

  作为计算机的计算单元,其运算能力方面,可能出现如下瓶颈:

  1. 用户态进程 CPU 占用率很高

  2. 系统态 (内核态) CPU 占用率很高

  测试 CPU 的运算性能,通常是通过计算圆周率来测试 CPU 的浮点运算能力和稳定性。据说 Pentium CPU 的一个运算 bug 就是通过计算圆周率来发现的。圆周率的计算方法,通常是计算小数点后 104 万位,通过比较运算时间来评测 CPU 的运算能力。

  常用工具:

  SUPER PI(π)

  Wprime 与 SuperPI 不同的是,可以支持多核 CPU 的运算速度测试

  FritzChess 一款国际象棋测试软件,测试每秒钟可运算的步数

  突破 CPU 的运算瓶颈,一般只能靠花钱。比如提高时钟频率,提高 L1,L2 cache 容量或不断追求新一代的 CPU 架构:

  Core -> Nehalem(E55x,如 r710,dsc1100) -> Westmere –> Sandy Bridge

  3.1.2 调度性能瓶颈

  CPU 除了负责计算之外,另一个非常重要的功能就是调度。在调度方面,CPU 可能会出现如下性能瓶颈:

  Load 平均值超过了系统可承受的程度

  IOWait 占比过高,导致 Load 上升或是引入新的磁盘瓶颈

  Context Switch 过高,导致 CPU 就像个搬运工一样,频繁在寄存器 (CPU Register) 和运行队列 (run queue) 之间奔波

  硬中断 CPU 占比接近于 100%

  软中断 CPU 占比接近于 100%

  超线程

  超线程芯片可以使得当前线程在访问内存的间隙,处理器可以使用它的机器周期去执行另外一个线程。一个超线程的物理 CPU 可以被 kernel 看做是两个独立的 CPU。

  3.2 典型监控参数

  3.2.1 参数含义

  Load

  Load 是指 CPU 所有内核正在处理的任务加上处于等待队列中的进程数之和。

  处于等待队列 (run queue) 中的进程包括 TASK_RUNNING 和 TASK_UNINTERRUPTIBLE 两种状态的任务:

  ? 处于可运行状态的进程

  ? 等待不可中断任务的进程

  在一个双核的系统中,如果两个进程正在执行,有四个进程处于 run quque 当中,那么 load 就是 6

  Nice%

  用户进程空间内,通过调用 nice 或 setpriority 系统调用改变过优先级的进程的 CPU 占用率

  Iowait%

  CPU 等待 IO 操作的时间

  Idle%

  CPU 空闲时间

  Intr/s#p# 分页标题 #e#

  每秒钟处理的中断数

  Hi%

  服务于 IRQs 的时间占比

  Si%

  服务于 Soft IRQs 的时间占比

  St%

  关于 st 的解释,在 IBM 的一份文档里,有一段描述:

  IBM’s definition of steal time is actually pretty good:

  Steal time is the percentage of time a virtual CPU waits for a real CPU while the hypervisor is servicing another virtual processor.

  3.3 工作原理

  为了更好地理解 CPU 的性能参数,需要了解如下一些概念

  3.3.1 进程及进程调度算法

  什么是线程

  图 3:进程和线程的数据结构

  2. 进程的状态

  可运行状态 (TASK_RUNNING)

  不可中断的等待状态 (TASK_UNINTERRUPTIBLE)

  暂停状态 (TASK_STOPPED)

  跟踪状态 (TASK_TRACED)

  僵死状态 (EXIT_ZOMBIE)

  问题 Wait io% 包含在 idle% 当中吗?

  从下面 top 实例可以看出,wait io% 不属于 idle%,等 IO 的过程被叫做 uninterruptible sleep

  Cpu1 : 2.7%us, 3.0%sy, 0.0%ni, 3.7%id, 89.7%wa, 0.0%hi, 1.0%si, 0.0%st

  从性能测试角度来看,我倾向于这样理解线程:

  1. 线程和进程的确不同,因为他们可以共享进程的资源,如地址空间等。因此在上下文切换的过程中可能会产生较小的性能损耗。

  2. 站在调度器 (scheduler) 的角度来说,线程就是一个进程,或者说是一个轻量级的进程 (Light Weight Process)。Kernel 实际上就是通过轻量级的进程来支持多线程应用程序的。我们经常用的线程开发库 pthread 就是通过将轻量级进程和线程关联起来,来实现的。这样既可以实现资源的共享,又可以让每个线程被调度器独立调度。

  2. 进程的状态

  可运行状态 (TASK_RUNNING)

  不可中断的等待状态 (TASK_UNINTERRUPTIBLE)

  暂停状态 (TASK_STOPPED)

  跟踪状态 (TASK_TRACED)

  僵死状态 (EXIT_ZOMBIE)

  问题 Wait io% 包含在 idle% 当中吗?

  从下面 top 实例可以看出,wait io% 不属于 idle%,等 IO 的过程被叫做 uninterruptible sleep

  Cpu1 : 2.7%us, 3.0%sy, 0.0%ni, 3.7%id, 89.7%wa, 0.0%hi, 1.0%si, 0.0%st

  3.3.4 硬中断

  性能测试中关注的中断,主要由自于 IO 设备所产生,如键盘的一次按键,网卡的收报等等。

  IRQ

  IO 设备所发出的 IRQ(Interrupt ReQuest) 请求叫做中断请求 (可屏蔽中断)

  每个能够发出中断的 IO 设备都有一个 IRQ 输出线 (部分高级前兆网卡,和大部分万兆网卡都多条 IRQ 输出线)。每条 IRQ 输出线和可编程中断控制器 (Programmable Interrupt Controller) 引脚相关联。

  每个 IRQ 输出线的中断信号,只能被一个 CPU core 处理,IRQ 线从 0 开始编号。

  如何观察 IRQ 的状态:

  问题 3:大量的中断,是否会使 CPU 响应中断成为瓶颈呢?

  答案是一般不会,中断享有最高的优先级,有硬件中断发生时,CPU 会立即停下手中的工作,响应中断,并调用相应中断处理程序。瓶颈一般发生在中断处理程序。

  IRQ 硬件中断是否意味着不会出现瓶颈呢?瓶颈有可能出现在中断的服务例程中,看下面的流程图:

  IRQ 在多处理器上的分发:

  遵循对称多处理模型,每个 IO 中断的处理时间片是相同的,均匀分配。Kernel 通过中断向量表来将中断信号发送到特定的 CPU 上去。

  在必要的时候,Linux 2.6 利用 kirqd 的内核线程来纠正 IRQ 在 CPU 上的分配。kirqd 线程周期性的执行扫描每个 CPU 处理的中断个数,发现不均衡时重新调整 CPU 的负载。

  下面的案例表明,IRQ 在 CPU 上的分配不够均衡,因为 8 个 CPU,只有 4 个 CPU 有负载:

  性能测试中关注的中断,主要由自于 IO 设备所产生,如键盘的一次按键,网卡的收报等等。

  IRQ

  IO 设备所发出的 IRQ(Interrupt ReQuest) 请求叫做中断请求 (可屏蔽中断)

  每个能够发出中断的 IO 设备都有一个 IRQ 输出线 (部分高级前兆网卡,和大部分万兆网卡都多条 IRQ 输出线)。每条 IRQ 输出线和可编程中断控制器 (Programmable Interrupt Controller) 引脚相关联。

  每个 IRQ 输出线的中断信号,只能被一个 CPU core 处理,IRQ 线从 0 开始编号。

  问题 3:大量的中断,是否会使 CPU 响应中断成为瓶颈呢?

  答案是一般不会,中断享有最高的优先级,有硬件中断发生时,CPU 会立即停下手中的工作,响应中断,并调用相应中断处理程序。瓶颈一般发生在中断处理程序。

  IRQ 硬件中断是否意味着不会出现瓶颈呢?瓶颈有可能出现在中断的服务例程中,看下面的流程图:

  IRQ 在多处理器上的分发:

  遵循对称多处理模型,每个 IO 中断的处理时间片是相同的,均匀分配。Kernel 通过中断向量表来将中断信号发送到特定的 CPU 上去。

  在必要的时候,Linux 2.6 利用 kirqd 的内核线程来纠正 IRQ 在 CPU 上的分配。kirqd 线程周期性的执行扫描每个 CPU 处理的中断个数,发现不均衡时重新调整 CPU 的负载。

  下面的案例表明,IRQ 在 CPU 上的分配不够均衡,因为 8 个 CPU,只有 4 个 CPU 有负载:

文章分类:性能测试

Link http://www.ltesting.net/ceshi/ceshijishu/xncs/2012/1130/205763.html

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册