Python性能分析工具


本文主要講了如何使用 timeperfline_profiler

測試python文件

call.py

def call():
    return True

for i in range(10000000):
    call()

time使用

time python call.py

  • real 總耗時 1.488秒
  • user 用戶態耗時 1.255 秒
  • sys 內核態耗時0.230秒

time

perf使用

perf --help 之后可以看到perf的二級命令。

序號 命令 作用
1 annotate 解析perf record生成的perf.data文件,顯示被注釋的代碼。
2 archive 根據數據文件記錄的build-id,將所有被采樣到的elf文件打包。利用此壓縮包,可以再任何機器上分析數據文件中記錄的采樣數據。
3 bench perf中內置的benchmark,目前包括兩套針對調度器和內存管理子系統的benchmark。
4 buildid-cache 管理perf的buildid緩存,每個elf文件都有一個獨一無二的buildid。buildid被perf用來關聯性能數據與elf文件。
5 buildid-list 列出數據文件中記錄的所有buildid。
6 diff 對比兩個數據文件的差異。能夠給出每個符號(函數)在熱點分析上的具體差異。
7 evlist 列出數據文件perf.data中所有性能事件。
8 inject 該工具讀取perf record工具記錄的事件流,並將其定向到標准輸出。在被分析代碼中的任何一點,都可以向事件流中注入其它事件。
9 kmem 針對內核內存(slab)子系統進行追蹤測量的工具
10 kvm 用來追蹤測試運行在KVM虛擬機上的Guest OS。
11 list 列出當前系統支持的所有性能事件。包括硬件性能事件、軟件性能事件以及檢查點。
12 lock 分析內核中的鎖信息,包括鎖的爭用情況,等待延遲等。
13 mem 內存存取情況
14 record 收集采樣信息,並將其記錄在數據文件中。隨后可通過其它工具對數據文件進行分析。
15 report 讀取perf record創建的數據文件,並給出熱點分析結果。
16 sched 針對調度器子系統的分析工具。
17 script 執行perl或python寫的功能擴展腳本、生成腳本框架、讀取數據文件中的數據信息等。
18 stat 執行某個命令,收集特定進程的性能概況,包括CPI、Cache丟失率等。
19 test perf對當前軟硬件平台進行健全性測試,可用此工具測試當前的軟硬件平台是否能支持perf的所有功能。
20 timechart 針對測試期間系統行為進行可視化的工具
21 top 類似於linux的top命令,對系統性能進行實時分析。
22 trace 關於syscall的工具。
23 probe 用於定義動態檢查點。

全局性概況:

perf list 查看當前系統支持的性能事件;

perf bench 對系統性能進行摸底;

perf test 對系統進行健全性測試;

perf stat 對全局性能進行統計;

全局細節:

perf top 可以實時查看當前系統進程函數占用率情況;

perf probe 可以自定義動態事件;

特定功能分析:

perf kmem 針對slab子系統性能分析;

perf kvm 針對kvm虛擬化分析;

perf lock 分析鎖性能;

perf mem 分析內存slab性能;

perf sched 分析內核調度器性能;

perf trace 記錄系統調用軌跡;

最常用功能perf record,可以系統全局,也可以具體到某個進程,更甚具體到某一進程某一事件;可宏觀,也可以很微觀。

perf record –e cpu-clock python call.py
pref record 記錄信息到perf.data;

perf report 生成報告;

perf diff 對兩個記錄進行diff;

perf evlist 列出記錄的性能事件;

perf annotate 顯示perf.data函數代碼;

perf archive 將相關符號打包,方便在其它機器進行分析;

perf script 將perf.data輸出可讀性文本;

可視化工具perf timechart

perf timechart record記錄事件;

perf timechart生成output.svg文檔;

關於perf top界面常用命令如下:

h:顯示幫助,即可顯示詳細的幫助信息。

UP/DOWN/PGUP/PGDN/SPACE:上下和翻頁。

a:annotate current symbol,注解當前符號。能夠給出匯編語言的注解,給出各條指令的采樣率。

d:過濾掉所有不屬於此DSO的符號。非常方便查看同一類別的符號。

P:將當前信息保存到perf.hist.N中。

perf top常用選項有:

-e :指明要分析的性能事件。

-p :Profile events on existing Process ID (comma sperated list). 僅分析目標進程及其創建的線程。

-k :Path to vmlinux. Required for annotation functionality. 帶符號表的內核映像所在的路徑。

-K:不顯示屬於內核或模塊的符號。

-U:不顯示屬於用戶態程序的符號。

-d :界面的刷新周期,默認為2s,因為perf top默認每2s從mmap的內存區域讀取一次性能數據。

-g:得到函數的調用關系圖。

perf top --call-graph [fractal],路徑概率為相對值,加起來為100%,調用順序為從下往上。

perf top --call-graph graph,路徑概率為絕對值,加起來為該函數的熱度。

image

perf stat

perf stat用於運行指令,並分析其統計結果。雖然perf top也可以指定pid,但是必須先啟動應用才能查看信息。

perf stat能完整統計應用整個生命周期的信息。

命令格式為:

perf stat [-e | --event=EVENT] [-a]
perf stat [-e | --event=EVENT] [-a] — [ ]

下面簡單看一下perf stat 的輸出:

[root@master ~]# perf stat
Performance counter stats for 'system wide':

40904.820871 cpu-clock (msec) # 5.000 CPUs utilized
18,132 context-switches # 0.443 K/sec
1,053 cpu-migrations # 0.026 K/sec
2,420 page-faults # 0.059 K/sec
3,958,376,712 cycles # 0.097 GHz (49.99%)
574,598,403 stalled-cycles-frontend # 14.52% frontend cycles idle (49.98%)
9,392,982,910 stalled-cycles-backend # 237.29% backend cycles idle (50.00%)
1,653,185,883 instructions # 0.42 insn per cycle
# 5.68 stalled cycles per insn (50.01%)
237,061,366 branches # 5.795 M/sec (50.02%)
18,333,168 branch-misses # 7.73% of all branches (50.00%)

​ 8.181521203 seconds time elapsed

輸出解釋如下:

cpu-clock:任務真正占用的處理器時間,單位為ms。CPUs utilized = task-clock / time elapsed,CPU的占用率。

context-switches:程序在運行過程中上下文的切換次數。

CPU-migrations:程序在運行過程中發生的處理器遷移次數。Linux為了維持多個處理器的負載均衡,在特定條件下會將某個任務從一個CPU遷移到另一個CPU。

CPU遷移和上下文切換:發生上下文切換不一定會發生CPU遷移,而發生CPU遷移時肯定會發生上下文切換。發生上下文切換有可能只是把上下文從當前CPU中換出,下一次調度器還是將進程安排在這個CPU上執行。

page-faults:缺頁異常的次數。當應用程序請求的頁面尚未建立、請求的頁面不在內存中,或者請求的頁面雖然在內存中,但物理地址和虛擬地址的映射關系尚未建立時,都會觸發一次缺頁異常。另外TLB不命中,頁面訪問權限不匹配等情況也會觸發缺頁異常。

cycles:消耗的處理器周期數。如果把被ls使用的cpu cycles看成是一個處理器的,那么它的主頻為2.486GHz。可以用cycles / task-clock算出。

stalled-cycles-frontend:指令讀取或解碼的質量步驟,未能按理想狀態發揮並行左右,發生停滯的時鍾周期。

stalled-cycles-backend:指令執行步驟,發生停滯的時鍾周期。

instructions:執行了多少條指令。IPC為平均每個cpu cycle執行了多少條指令。

branches:遇到的分支指令數。branch-misses是預測錯誤的分支指令數。

其他常用參數

-a, --all-cpus 顯示所有CPU上的統計信息
-C, --cpu 顯示指定CPU的統計信息
-c, --scale scale/normalize counters
-D, --delay ms to wait before starting measurement after program start
-d, --detailed detailed run - start a lot of events
-e, --event event selector. use 'perf list' to list available events
-G, --cgroup monitor event in cgroup name only
-g, --group put the counters into a counter group
-I, --interval-print
print counts at regular interval in ms (>= 10)
-i, --no-inherit child tasks do not inherit counters
-n, --null null run - dont start any counters
-o, --output 輸出統計信息到文件
-p, --pid stat events on existing process id
-r, --repeat repeat command and print average + stddev (max: 100, forever: 0)
-S, --sync call sync() before starting a run
-t, --tid stat events on existing thread id
...

示例

前面統計程序的示例,下面看一下統計CPU信息的示例:

perf stat python call.py

image

perf top -C 0

image

Flame Graph

FlameGraph

1.抓取perf信息並轉換

perf record -F 99 -a -g -- sleep 60
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl out.kern_folded > kernel.svg

line_profiler使用

逐行分析python代碼

# test.py
import line_profiler

@profile
def fib(n):
    # 文件名aaa.py
    a, b = 0, 1
    for i in range(0, n):
        a, b = b, a+b
    return a
fib(5)

D:\PythonProject\interview> kernprof -l -v test.py

Wrote profile results to test.py.lprof
Timer unit: 1e-06 s

Total time: 3.61e-05 s
File: test.py
Function: fib at line 253

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
   253                                           @profile
   254                                           def fib(n):
   255                                               # 文件名aaa.py
   256         1         15.3     15.3     42.4      a, b = 0, 1
   257         6          4.0      0.7     11.1      for i in range(0, n):
   258         5         16.4      3.3     45.4          a, b = b, a+b
   259         1          0.4      0.4      1.1      return a

  • Total Time:測試代碼的總運行時間
  • Line:代碼行號
  • Hits:表示每行代碼運行的次數
  • Time:每行代碼運行的總時間
  • Per Hits:每行代碼運行一次的時間
  • % Time:每行代碼運行時間的百分比
  • 從分析結果可以看出:第258行代碼運行時間最長

參考資料

系統級性能分析工具 — Perf:http://blog.csdn.net/zhangskd/article/details/37902159/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM