どのようにPERFツール

PERFプロフィール

PERFは、パフォーマンス分析のために使用されるソフトウェアツールです。

それを通じて、アプリケーションはPMU、トレースポイントとパフォーマンス統計のための特別なカウンターのカーネルを利用することができます。それだけでなく、(スレッドごと)アプリケーションを指定し、完全にあなたのアプリケーションにおけるパフォーマンスのボトルネックを理解するためには、もちろん、あなたが同時にカーネルやアプリケーションコードを分析することができ、コアの問題のパフォーマンスを分析するためにも使用することができ、パフォーマンスの問題を分析することができます。

最初は、それが最初に2.6.31に登場し、パフォーマンスカウンタと呼ばれています。それ以来、彼は最も活発なカーネル開発分野の一つとなっています。PERFは、もはや単なる抽象的なPMUとしてではなく、パフォーマンス関連イベントのすべてを処理することができませんので、2.6.32では正式に、パフォーマンスイベントと改名されました。

使用PERFは、あなたが実行中に、ハードウェアインシデントを分析することができ、このような命令は、プロセッサクロックサイクルを引退し、その上、また、そのようなページフォールトやプロセススイッチングなどのソフトウェアイベントを、分析することができます。

これは、IPC、IPCコードが良好な低使用率CPUを示していないなどの分析特性の多数を持つパフォーマンス・は、例えば、クロック・サイクル当たりの命令のパーフォレーション数を用いて計算することができる、と呼ぶことができます。PERFはまた、関数レベルのサンプリングプログラムは、パフォーマンスのボトルネックを把握することができ、その上、どこプログラムです。PERFはまた、straceのを置き換えることができ、あなたが動的カーネル・プローブ・ポイントを追加することができます、また、スケジューラを測定するために、良いか悪いかのベンチマークを行うことができます

 

 

PERFの基本的な使用

次のプログラム例を調べます。前記ロンガ機能()時間の無駄より、非常に長いサイクルです。FOO1のfoo2は機能と、それぞれ10倍、100倍の関数を呼び出します

 1 //test.c 
 2 void longa() 
 3 { 
 4   int i,j; 
 5   for(i = 0; i < 1000000; i++) 
 6   j=i; //am I silly or crazy? I feel boring and desperate. 
 7 } 
 8  
 9 void foo2() 
10 { 
11   int i; 
12   for(i=0 ; i < 10; i++) 
13        longa(); 
14 } 
15  
16 void foo1() 
17 { 
18   int i; 
19   for(i = 0; i< 100; i++) 
20      longa(); 
21 } 
22  
23 int main(void) 
24 { 
25   foo1(); 
26   foo2(); 
27 }

性能调优工具如 perf,Oprofile 等的基本原理都是对被监测对象进行采样,最简单的情形是根据 tick 中断进行采样,即在 tick 中断内触发采样点,在采样点里判断程序当时的上下文。假如一个程序 90% 的时间都花费在函数 foo() 上,那么 90% 的采样点都应该落在函数 foo() 的上下文中。运气不可捉摸,但我想只要采样频率足够高,采样时间足够长,那么以上推论就比较可靠。因此,通过 tick 触发采样,我们便可以了解程序中哪些地方最耗时间,从而重点分析。

 

Perf list,perf 事件

使用 perf list 命令可以列出所有能够触发 perf 采样点的事件。比如

$ perf list 
 List of pre-defined events (to be used in -e): 
 cpu-cycles OR cycles [Hardware event] 
 instructions [Hardware event] 
…
 cpu-clock [Software event] 
 task-clock [Software event] 
 context-switches OR cs [Software event] 
…
 ext4:ext4_allocate_inode [Tracepoint event] 
 kmem:kmalloc [Tracepoint event] 
 module:module_load [Tracepoint event] 
 workqueue:workqueue_execution [Tracepoint event] 
 sched:sched_{wakeup,switch} [Tracepoint event] 
 syscalls:sys_{enter,exit}_epoll_wait [Tracepoint event] 
…

Hardware Event 是由 PMU 硬件产生的事件,比如 cache 命中,当您需要了解程序对硬件特性的使用情况时,便需要对这些事件进行采样;

Software Event 是内核软件产生的事件,比如进程切换,tick 数等 ;

Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数等。

 

Perf stat

有些程序慢是因为计算量太大,其多数时间都应该在使用 CPU 进行计算,这叫做 CPU bound 型;有些程序慢是因为过多的 IO,这种时候其 CPU 利用率应该不高,这叫做 IO bound 型;对于 CPU bound 程序的调优和 IO bound 的调优是不同的。

 1 $perf stat ./t1 
 2  Performance counter stats for './t1': 
 3  
 4  262.738415 task-clock-msecs # 0.991 CPUs 
 5  2 context-switches # 0.000 M/sec 
 6  1 CPU-migrations # 0.000 M/sec 
 7  81 page-faults # 0.000 M/sec 
 8  9478851 cycles # 36.077 M/sec (scaled from 98.24%) 
 9  6771 instructions # 0.001 IPC (scaled from 98.99%) 
10  111114049 branches # 422.908 M/sec (scaled from 99.37%) 
11  8495 branch-misses # 0.008 % (scaled from 95.91%) 
12  12152161 cache-references # 46.252 M/sec (scaled from 96.16%) 
13  7245338 cache-misses # 27.576 M/sec (scaled from 95.49%) 
14  
15   0.265238069 seconds time elapsed 
16  
17 上面告诉我们,程序 t1 是一个 CPU bound 型,因为 task-clock-msecs 接近 1

对 t1 进行调优应该要找到热点 ( 即最耗时的代码片段 ),再看看是否能够提高热点代码的效率。

缺省情况下,除了 task-clock-msecs 之外,perf stat 还给出了其他几个最常用的统计信息:

Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO。

Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。

Cache-misses:程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好

CPU-migrations:表示进程 t1 运行过程中发生了多少次 CPU 迁移,即被调度器从一个 CPU 转移到另外一个 CPU 上运行。

Cycles:处理器时钟,一条机器指令可能需要多个 cycles,

Instructions: 机器指令数目。

IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。

Cache-references: cache 命中的次数

Cache-misses: cache 失效的次数。

通过指定 -e 选项,您可以改变 perf stat 的缺省事件 ( 关于事件,在上一小节已经说明,可以通过 perf list 来查看 )。假如您已经有很多的调优经验,可能会使用 -e 选项来查看您所感兴趣的特殊的事件

 

Perf record  解读 report

使用 top 和 stat 之后,您可能已经大致有数了。要进一步分析,便需要一些粒度更细的信息。比如说您已经断定目标程序计算量较大,也许是因为有些代码写的不够精简。那么面对长长的代码文件,究竟哪几行代码需要进一步修改呢?这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果。

您的调优应该将注意力集中到百分比高的热点代码片段上,假如一段代码只占用整个程序运行时间的 0.1%,即使您将其优化到仅剩一条机器指令,恐怕也只能将整体的程序性能提高 0.1%。俗话说,好钢用在刀刃上,不必我多说了。

1 perf record  ./t1 
2 perf report
 1 Samples: 107  of event 'cycles', Event count (approx.): 889407873
 2 Overhead  Command  Shared Object      Symbol
 3   99.26%  t1       t1                 [.] longa
 4    0.61%  t1       [kernel.kallsyms]  [k] nmi
 5    0.03%  t1       [kernel.kallsyms]  [k] __hrtimer_next_event_base
 6    0.03%  t1       [kernel.kallsyms]  [k] __vma_adjust
 7    0.02%  t1       ld-2.30.so         [.] 0x000000000001e378
 8    0.02%  t1       [kernel.kallsyms]  [k] filemap_map_pages
 9    0.02%  t1       [kernel.kallsyms]  [k] do_user_addr_fault
10    0.01%  t1       [kernel.kallsyms]  [k] move_page_tables
11    0.00%  perf     [kernel.kallsyms]  [k] perf_event_comm_output
12    0.00%  perf     [kernel.kallsyms]  [k] perf_pmu_enable.part.0
13    0.00%  perf     [kernel.kallsyms]  [k] sched_clock
14    0.00%  perf     [kernel.kallsyms]  [k] native_write_msr

不出所料,hot spot 是 longa( ) 函数

 

おすすめ

転載: www.cnblogs.com/mysky007/p/12307642.html