perf是Linux内核内置的性能分析工具。从内核版本2.6.31开始出现该工具,如果没有安装,可以使用以下命令进行安装
yum -y install perf.x86_64
这里我们主要介绍一下如何使用,一些具体的背景知识,请查阅参考链接。
perf list列出能查看的性能事件,这里可以看做是事件的一些分类
#perf list -h
usage: perf list [hw|sw|cache|tracepoint|pmu|event_glob]
可以进一步查看hw(Hardware)分类的事件,只举例,不再列举
#perf list hw
cpu-cycles OR cycles [Hardware event]
instructions [Hardware event]
cache-references [Hardware event]
cache-misses [Hardware event]
branch-instructions OR branches [Hardware event]
branch-misses [Hardware event]
stalled-cycles-frontend OR idle-cycles-frontend [Hardware event]
stalled-cycles-backend OR idle-cycles-backend [Hardware event]
ref-cycles [Hardware event]
一个简单的c程序,foo1和foo2分别调用longa()100次和10次
# cat perf.c
//test.c
void longa()
{
int i,j;
for(i = 0; i < 1000000; i++)
j=i; //am I silly or crazy? I feel boring and desperate.
}
void foo2()
{
int i;
for(i=0 ; i < 10; i++)
longa();
}
void foo1()
{
int i;
for(i = 0; i< 100; i++)
longa();
}
int main(void)
{
foo1();
foo2();
}
# cc perf.c
# perf stat ./a.out
Performance counter stats for './a.out':
331.445189 task-clock (msec) # 0.999 CPUs utilized
0 context-switches # 0.000 K/sec
1 cpu-migrations # 0.003 K/sec
104 page-faults # 0.314 K/sec
571,668,722 cycles # 1.725 GHz [83.39%]
241,223,545 stalled-cycles-frontend # 42.20% frontend cycles idle [83.41%]
2,915,367 stalled-cycles-backend # 0.51% backend cycles idle [66.82%]
550,449,588 instructions # 0.96 insns per cycle
# 0.44 stalled cycles per insn [83.41%]
110,422,677 branches # 333.155 M/sec [83.40%]
6,461 branch-misses # 0.01% of all branches [83.10%]
0.331874225 seconds time elapsed
以上也可以通过-e选项,指定需要分析的事件,也就是perf list列出的事件,多个事件可以通过逗号分隔。
如下,添加 cache-references,cache-misses选项查看cache相关的事件。
#perf stat -e cache-references,cache-misses ./a.out
Performance counter stats for './a.out':
10,718 cache-references
2,249 cache-misses # 20.983 % of all cache refs
0.340821068 seconds time elapsed
打开一个窗口,新建一个数据库,并用pgbech进行数据写入测试
hank=# \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# create database perf_database;
CREATE DATABASE
postgres=# grant all on DATABASE perf_database to hank;
GRANT
postgres=# \q
$pgbench -i perf_database -h 127.0.0.1 -U hank perf_database
dropping old tables...
NOTICE: table "pgbench_accounts" does not exist, skipping
NOTICE: table "pgbench_branches" does not exist, skipping
NOTICE: table "pgbench_history" does not exist, skipping
NOTICE: table "pgbench_tellers" does not exist, skipping
creating tables...
generating data...
100000 of 100000 tuples (100%) done (elapsed 0.06 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done.
执行压测pgbench
pgbench -M prepared -n -r -P 1 -h 127.0.0.1 -U hank perf_database -c 32 -j 32 -T 600
另外一个窗口使用perf top 进行查看,如下
perf top -agv -F 1000
命令参数见perf top --help,这里a指所有cpu,-g表示打开call-graph,-v表示展示更多信息,-F 表示频率
先看一个简单的例子:
还是上面c程序例子
编译
cc perf.c
收集
perf record -g ./a.out
生成报告
perf report -vg
可以看到foo1和foo2 在cpu使用上的比例,分别是90.76%和8.88%,基本符合代码,代码中一个循环100次,一个10次
再看一个postgresql使用pgbench的例子:
一个窗口执行pgbench
pgbench -M prepared -n -r -P 1 -U hank perf_database -c 32 -j 32 -T 600
另外的窗口收集信息
收集20秒,当然也可以ctrl+c终止。
perf record -avg -- sleep 20
生成报告
perf report -v -n -g
也可以使用–stdion查看
perf report -v -n -g --stdio
参考:
https://www.ibm.com/developerworks/cn/linux/l-cn-perf1/
https://www.ibm.com/developerworks/cn/linux/l-cn-perf2/
https://github.com/digoal/blog/blob/master/201611/20161129_01.md