linux性能测试与运行分析

------静态(开发阶段)测试

gprof

gprofGNU工具之一,它在编译的时候在每个函数的出入口加入了profiling的代码,运行时统计程序在用户态的执行信息,可以得到每个函数的调用次数、执行时间、调用关系等信息,简单易懂。适合于查找用户级程序的性能瓶颈,对于很多时间都在内核态执行的程序,gprof不适合

gprof默认只统计用户函数的信息,如果要统计库函数,应链接libc_p.a库,才可以产生库函数的profiling信息,如下:

gcc -Wall -g -pg -lc_p example.c -o example

oprofile

oprofile也是一个开源的profiling工具,它使用硬件调试寄存器来统计信息,进行 profiling的开销比较小,而且可以对内核进行profiling。它统计的信息非常的多,可以得到cache的缺失率,memory的访存信息, 分支预测错误率等等,这些信息gprof是得不到的,但是对于函数调用次数,它是不能够得到的。

具体参见:http://blog.csdn.net/guogaofeng1219/article/details/5971149

------运行时测试

下面的命令会释放pagecache,   dentries  and  inodes

sync;echo 3 > /proc/sys/vm/drop_caches

这可以消除已加载cache对程序性能的影响

磁盘速度测试dd

在使用前首先了解两个特殊设备
/dev/null 伪设备,回收站.写该文件不会产生IO
/dev/zero 伪设备,会产生空字符流,对它不会产生IO

例如测试磁盘写速度
time dd if=/dev/zero of=/test.dbf bs=8k count=300000
测试磁盘读速度
 time dd if=/dev/mapper/VolGroup00-LogVol00 of=/dev/null bs=8k

ifstat

监控网卡传输速度
      eth0
 KB/s in  KB/s out
    0.18      0.39
    0.12      0.37
    0.12      0.25

iostat

显示设备(磁盘)和CPU使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;1 10表示,数据显示每隔1秒刷新一次,共显示10次。

$: iostat -k 1 10

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.50    0.00   13.57    0.00    0.00   85.93


Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.00         0.00         0.00          0          0
hdc               0.00         0.00         0.00          0          0

kernel将cpu归为3个状态:idle,iowait,busy;idle是真正的idle,没活可干,没有进程是runnale的,cpu空闲;iowait时cpu没法干活(需要的数据还没就绪呢,所以叫wait),这时候cpu也空闲;busy就是在干活。idle和iowait时虽然cpu都是空闲的,但是将这两个状态区分开是很有意义的,因为iowait可以衡量由io问题导致的cpu空闲。

------查看进程使用的资源

/proc/<pid>

例如fd目录:打开的文件(包括socket)
smaps: 进程虚拟内存分布

netstat

进程监听端口、连接信息(对端与本端端口)、进程名等

lsof

-c<进程名> 列出指定进程所打开的文件
-u 列出UID号进程详情
-i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p pid  列出指定进程号所打开的文件
filename 显示打开指定文件的进程信息

lsof -i TCP:9999
a.out   15747 root    7u  IPv4 515314       TCP localhost:distinct->localhost:41471 (ESTABLISHED)
a.out   15747 root    8u  IPv4 515316       TCP localhost:distinct->localhost:41472 (ESTABLISHED)
其中515314是进程的文件描述符,而41471是对端端口号,这结合了/proc/<pid>/fd与netstat的信息

------查看进程运行位置


pstack


能查看进程的线程栈,但只支持32位

strace 

stace -p <pid> 查看进程当前调用的库函数(包括参数值)

------实际运用

简单来说,我们看iostat中%user的比例,如果比较高,一般是程序在进行较复杂的计算,比如排序,如果%user低,而%system高,说明大部分时间花在io上,再结合磁盘利用百分比和%wait来看,如果他们也比较高,说明的确有高速的io访问,或者磁盘或者网卡本身出现了瓶颈,导致io较慢,如果这个百分比比较低,那就是进程对io函数的使用不当,比如read/write较小,或者使用select/poll去轮询大量非活动连接
如果iostat中%user %system都比较低,而程序是个网络连接程序,那可能是到对方连接速度过慢,需要看ping中的返回时间来确定

测试两条命令:
time dd if=/dev/zero of=/test.dbf bs=32 count=10000000

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                        1.02    0.00   48.47    0.00    0.00   50.51


Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
hdc               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

time dd if=/dev/zero of=/test.dbf2 bs=8k count=300000

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                           0.58    0.00   64.53    2.91    0.00   31.98


Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00 24522.77    0.00  219.80     0.00 98974.26   900.58    20.99   95.50   1.86   40.79
hdc               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

两条dd命令运行都运行iostat检测cpu与磁盘使用百分比
发现cpu的利用率都是很高,但是第2条命令运行时,磁盘的利用率比较高,并且时常有一定的iowait(第一条几乎为0)
这正好印证了read/write的效率,当粒度较小时,大部分的时间花在了从系统cache与进程buffer间的传输上,而磁盘其实是比较清闲的,反之,则磁盘比较繁忙,会带来一定的iowait,但是cpu在io可用时,也要频繁的数据传输,带来较高的%system,如果磁盘出现问题,io比较慢,就会%system比较低,%wait或者%idle比较高

测试一个echo server(poll实现) 和一个echo client的例子
客户端到服务端有1000个连接,200个活动,每次全部活动连接试图发送32字节,然后接收会32字节的应答,读写使用readn/writen封装,客户端每秒发送/接收各10M
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                  0.51      0.00    41.84        0.00        0.00         57.65


Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
hdc               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
测试发现iostat时cpu使用率比较高(%system部分,说明并非是因为程序计算复杂),ifstat检测网卡传输速率也停留在较低的水平,strace发现进程大部分的调用是在read/write
然后查看gprof的统计结果,也定位在readn/writen部分,说明要改善readn/writen粒度
如果将单次收发字节数改为4096,启动10个这样的客户端,服务端就有10000个连接,2000个活动,客户端发送接收量不变,测试发现,cpu使用率比较高(%system部分),ifstat检测网卡传输速度仍然很低,而gprof的统计结果中,readn/writen的百分比比较低(上一种测试这个很高),strace发现主要的调用时readn/writen/poll,所以判断poll的机制造成了比较高的cpu占用率

虽然,我们都知道小粒度的read/write和poll都比较慢,但是对于一个不清楚代码的进程、或者一个比较大型的项目,而原有的读写部分代码又太多、太分散,我们几乎不可能重构全部不合理代码的时候,采用以上办法都能帮我们快速定位瓶颈所在

你可能感兴趣的:(linux性能测试与运行分析)