跳转至

程序性能测试和分析方法

性能工具

perf

这个工具可以显示一个程序的各种性能统计数据,包括CPU使用,缓存命中/未命中的次数,分支预测的准确性,以及更多。

-e:设置事件

perf stat

perf stat -e cpu-clock,task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,cache-references,cache-misses -p [PID]
perf stat -e cpu,clock,task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,cache-references,cache-misses command [arguments]
  • cpu-clock: 该进程实际运行的CPU时间(以毫秒为单位)。
  • task-clock: 任务运行的CPU时间(以毫秒为单位);通常情况下,这个值与cpu-clock相同,但是当程序中有多个线程时,这个值可能会大于cpu-clock
  • context-switches: 上下文切换的次数。
  • cpu-migrations: CPU迁移的次数。
  • page-faults: 页错误的次数。
  • cycles: CPU周期的数量。
  • instructions: 指令的数量。
  • cache-references: 缓存命中的次数。
  • cache-misses: 缓存未命中的次数。

比如执行命令:perf stat -e cpu-clock,task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,cache-references,cache-misses /bin/pki -n -H

 Performance counter stats for '/bin/pki':

       2.622641  task-clock-msecs         #      0.000 CPUs
            107  context-switches         #      0.041 M/sec
              0  CPU-migrations           #      0.000 M/sec
            652  page-faults              #      0.249 M/sec
        7580048  cycles                   #   2890.235 M/sec
        7605108  instructions             #      1.003 IPC
         318183  cache-references         #    121.322 M/sec
          95078  cache-misses             #     36.253 M/sec

    9.820330663  seconds time elapsed

这是perf stat的输出,它提供了关于/bin/pki执行过程中的一些性能统计信息。以下是每一行的解释:

  • task-clock-msecs:这是该进程实际运行的CPU时间(以毫秒为单位)。这里的2.622641毫秒意味着该进程在CPU上运行的时间总计是2.622641毫秒。

  • context-switches:这是进程的上下文切换次数。上下文切换是CPU从一个任务(或进程)切换到另一个任务(或进程)的过程。

  • CPU-migrations:这是进程在不同的CPU核心之间迁移的次数。如果这个数字较大,可能意味着进程的调度有些问题,因为频繁的迁移可能会导致缓存未命中率的增加,从而降低性能。

  • page-faults:这是进程的页面错误次数。页面错误是进程尝试访问的内存页不在其地址空间内,或者不在物理内存中,因此需要从磁盘上加载。

  • cycles:这是CPU执行的周期数。一个周期通常对应CPU的一个时钟滴答。

  • instructions:这是执行的指令数。这个数字越大,意味着该进程执行了更多的操作。

  • cache-references:这是CPU缓存的引用次数。它包括命中缓存的次数和未命中缓存的次数。

  • cache-misses:这是CPU缓存未命中的次数。如果这个数字占总缓存引用次数的比例较大,可能意味着程序的缓存利用率不高。

  • seconds time elapsed:这是命令执行的总时间(包括等待时间和运行时间)。

每个计数器后面的#号后的数字是每秒的事件数量(例如,每秒的上下文切换次数,每秒的CPU迁移次数等)。IPC(Instructions Per Cycle)是周期数与指令数的比率,用于衡量CPU的效率。在这个例子中,IPC是1.003,这意味着每个CPU周期大约可以完成1个指令,这是一个相当高的效率。

持续监控和报告

监控:

perf record

报告:

perf report

iostat

这个工具可以显示系统的I/O操作,包括每个设备的读写速度。

top

htop

free

这个命令可以显示系统的总体内存使用情况,包括已用和可用的内存。

pidstat

这个工具来监控进程的内存使用情况。 该资源一般在sysstat包中,可以通过下面命令安装:

  • On Debian/Ubuntu

    apt-get install sysstat
    
  • On CentOS/RHEL

    yum install sysstat
    

例如,你可以用以下命令每秒输出一次指定进程的内存使用情况:

pidstat -r -p [pid] -h 1

在上述命令中, -r 选项表示报告内存使用情况, -p 选项后面跟的是你要监控的进程的进程ID,1表示每秒输出一次。

如果你希望记录这些信息,你可以将输出重定向到一个文件:

pidstat -r -p [pid] -j -h 1 > mem_usage.txt

如果你想在一段时间内收集这些数据,你可以使用 timeout 命令:

timeout 60 pidstat -r -p [pid] -h 1 > mem_usage.txt

以上命令将会在60秒后停止数据收集。

请注意, pidstat 命令可能并不在所有系统中都预装,可能需要你手动安装 sysstat 包来获取它。

收集IO情况的,可以用 -d 选项:

pidstat -d -p [pid] -h 1 > io_usage.txt

/proc/[PID]/status

查看进程状态,单位都是KB:

  • Name: 进程名称。
  • State: 进程的当前状态。在你的例子中,S代表睡眠状态。
  • Tgid: 线程组ID,这个值与PID相同,表明这是一个线程组的主线程。
  • Pid: 进程ID。
  • PPid: 父进程ID,在你的例子中是1,表明这个进程是由init进程启动的。
  • TracerPid: 如果该进程正在被追踪(trace),这就是追踪它的进程的ID。在你的例子中,这个值为0,表示没有进程正在追踪它。
  • UidGid: 分别代表用户ID和组ID,这四个值代表真实用户ID、有效用户ID、保存的设置用户ID、和文件系统用户ID。

  • VmPeakVmSizeVmHWMVmRSSVmDataVmStkVmExeVmLibVmPTEVmSwap: 这些都是进程的内存使用信息。例如,VmRSS 是进程的驻留集大小,表示进程在物理内存中占用的空间量。

    • VmPeak: 进程所使用的虚拟内存的峰值,单位是KB。
    • VmSize: 进程现在使用的虚拟内存的总量,单位是KB。这包括了所有的代码、数据和共享库,以及通过sbrk、mmap等系统调用映射的页。
    • VmHWM: 进程所使用的物理内存的峰值,单位是KB。HWM 是 High Water Mark 的缩写,意思是"高水位标"。
    • VmRSS: 进程现在使用的物理内存的总量,单位是KB。RSS 是 Resident Set Size 的缩写,意思是"常驻集大小",指的是进程在物理内存中占用的部分的大小。
    • VmData: 进程的数据段大小,单位是KB。数据段通常包含了初始化和未初始化的数据。
    • VmStk: 进程的栈大小,单位是KB。
    • VmExe: 进程的文本段大小,单位是KB。文本段包含了程序的代码。
    • VmLib: 进程使用的共享库的总大小,单位是KB。
    • VmPTE: 进程页表条目的大小,单位是KB。页表是操作系统用来管理虚拟内存到物理内存映射的数据结构。
    • VmSwap: 进程被交换出去的虚拟内存的总量,单位是KB。如果这个值不为0,那么意味着你的系统可能内存不足,导致部分数据被交换到了硬盘上。
  • Threads: 进程中的线程数。你的进程只有一个线程。
  • voluntary_ctxt_switchesnonvoluntary_ctxt_switches: 自愿和非自愿的上下文切换次数。上下文切换是指CPU从一个进程或线程切换到另一个的过程。自愿的上下文切换通常发生在一个进程知道它将要等待一些条件(比如I/O操作完成),所以它自愿地将CPU让给其他进程。非自愿的上下文切换通常发生在一个进程用完了它的时间片,或者有更高优先级的进程需要运行,因此操作系统强制进行的上下文切换。

持续监控RSS值:

while [ 1 ]; do cat /proc/[pid]/status | grep RSS; sleep 0.2; done

numactl

dmidecode

speccpu

powertop

powerstat

turbostat

基准工具

unixbench

  • Memory

sysbench

  • CPU
  • Memory

lmbench

  • Memory

iometer

  • IO

iozone

  • IO

fio

  • IO

评论